在SAP ABAP裡使用註解@Inject模擬Java Spring
Recently I will deliver a session regarding dependency inversion principle to my team.
As Java Spring is already widely used in all other Java development teams in my site, some ABAPers are not well aware of its idea and implementation under the hood. In order for ABAPers to easily understand the mechanism of Java Spring dependency inversion, I wrote a prototype in ABAP after going through related Java source code of Spring.
Before I start, I perform the search in SCN. There are already several excellent blogs written regarding dependency injection in ABAP:
- ABAP Dependency Injection – An implementation approach
- Shoot Me Up ABAP
- Dependency Injection for ABAP
- MockA in github
Compared with those blogs, the advantage of my prototype is: it follows exactly the design of Java Spring, it is not needed for users to do any other manual dependency registration except a single annotation @Inject. So it is useful for ABAPers to understand Spring dependency internal implementation.
Let me begin with a simple example. In real world I have a switch. By pressing it, the lamp connected by that switch is turned on. With switch pressed for second time, the lamp is turned off. That’s all.
Implementation without using Dependency injection
I have an interface ZIF_SWITCHABLE with two simple methods:
And a ZCL_LAMP which simply implements this interface:
CLASS ZCL_LAMP IMPLEMENTATION.method ZIF_SWITCHABLE~OFF.
WRITE: / 'lamp off'.
endmethod.
method ZIF_SWITCHABLE~ON.
WRITE: / 'lamp on'.
endmethod.ENDCLASS.
And a switch which internally maintains the current switch status and a reference to ZIF_SWITCHABLE:
The switch has a push method to toggle:
METHOD push.
IF isswitchon = abap_true.
mo_switchable->off( ).
isswitchon = abap_false.
ELSE.
mo_switchable->on( ).
isswitchon = abap_true.
ENDIF.
ENDMETHOD.
And a setter method is needed to inject the switchable instance:
method SET_SWITCHABLE.
mo_switchable = io_switchable.endmethod.
These two classes and one interface are put to the following package:
Consumer code – version one without using dependency injection
Here the ZCL_SWITCH has tight dependency on ZCL_LAMP: it has to manually inject this dependency via setter method in line 11.
Let’s summarize how many manual / unnecessary operations are done by consumer:
- line 8: create lamp instance
- line 9: create switch instance
- line 11: connect switch with lamp
Implementation using ABAP Summer
I call my prototype as ABAP Summer just to show my admire on Java Spring
When the same requirement is implemented in Java Spring, the logic in line 11 could completely be avoided, with help of various powerful annotation like@Autowired, @Named, @Inject etc. Thanks to Java Spring container, lots of labor work has been done by it under the hood, saving lots of routine effort from application developers so that they can only concentrate on the core business logic. For example, in Java using Spring, all developers need to do is to add annotation @Inject on top of attribute switchable – in the runtime Spring will guarantee that the annotated implementation for this interface is instantiated automatically.
How can we simulate the similar logic of Spring now in ABAP Summer?
(1) Add the annotation @Inject to attribute mo_switchable, which tells ABAP summer “hey, I would like this attribute to be automatically injected with proper implementation in the runtime”.
Since I have no other way to add metadata in class attribute in ABAP – there is no first class annotation supported in ABAP – I have to use description field for simulation.
(2) And below is my consumer code, no more manual instance initialization and manual setter call. Very clean, isn’t it?
data(summer) = zcl_summer=>get_instance( ).data(lo_switch) = cast zcl_switch( summer->get_bean( EXPORTING iv_bean_name = 'ZCL_SWITCH' ) ).lo_switch->push( ).lo_switch->push( ).
Let’s make comparison. By using ABAP summer, consumer can simply get switch instance from container by passing bean technical name ( here again, I use Spring terminology “bean” to name those ABAP classes which owns an injected member attribute with @Inject ). This is exactly the way a Java developer doing daily work using Java Spring:
How does ABAP summer work?
There are lots of books written to illustrate the design of Java Spring, I read one of them listed below, and wrote this ABAP summer based on my understanding.
I draw a diagram below to explain the core method init of ABAP summer:
Last by not least, when you try this demo, after you copy the source code of ZCL_SWITCH to your system and activate it, NEVER forget to add this annotation in description field manually, as in ABAP, the attribute description is not stored in source code but in DB table.
More thought on ABAP annotation
The annotation in Java is a form of metadata which could be defined by application developer and are available in the runtime by Java reflection. It is a built-in language feature supported by JVM.
In ABAP there is no such first-class annotation supported. In CDS view, there are some grammar which have annotation-like style. You can append lots of annotation defined in SAP help to a CDS view.
However those annotation are not first-class annotation supported by ABAP language itself as well. It is just CDS view framework which parses the source code of these annotation and react accordingly. For details please see these two blogs of mine:
- My CDS view self study tutorial – Part 3 how is view source in Eclipse converted to ABAP view in the backend
- My CDS view self study tutorial – Part 4 how does annotation @OData.publish work
Further reading
I have written a series of blogs which compare the language feature among ABAP, JavaScript and Java. You can find a list of them below:
- Lazy Loading, Singleton and Bridge design pattern in JavaScript and in ABAP
- Functional programming – Simulate Curry in ABAP
- Functional Programming – Try Reduce in JavaScript and in ABAP
- Simulate Mockito in ABAP
- A simulation of Java Spring dependency injection annotation @Inject in ABAP
- Singleton bypass – ABAP and Java
- Weak reference in ABAP and Java
- Fibonacci Sequence in ES5, ES6 and ABAP
- Java byte code and ABAP Load
- How to write a correct program rejected by compiler: Exception handling in Java and in ABAP
- An small example to learn Garbage collection in Java and in ABAP
- String Template in ABAP, ES6, Angular and React
- Try to access static private attribute via ABAP RTTI and Java Reflection
- Local class in ABAP, Java and JavaScript
- Integer in ABAP, Java and JavaScript
要獲取更多Jerry的原創文章,請關注公眾號"汪子熙":
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24475491/viewspace-2723623/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SAP ABAP CDS view裡的註解在ABAP後臺是如何被解析的?View
- Java的Covariance設計原理和SAP ABAP的模擬實現Java
- 【Spring註解驅動開發】你還不會使用@Resource和@Inject註解?那你就out了!!Spring
- ABAP模擬Java Spring依賴注入(Dependency injection)的一個嘗試JavaSpring依賴注入
- SAP ABAP CGLIB(Code Generation Library)的模擬實現CGLib
- SAP ABAP Netweaver 裡的 ABAP 會話概念會話
- 在SAP CRM WebClient UI裡開啟ABAP Webdynpro頁面WebclientUI
- 在 SAPGUI 裡使用 ABAP 報表上傳 SAP UI5 應用到 ABAP 伺服器試讀版GUI伺服器
- 使用Java+SAP雲平臺+SAP Cloud Connector呼叫ABAP On-Premise系統裡的函式JavaCloudREM函式
- SAP ABAP Netweaver 裡的使用者會話概念會話
- SAP SEGW 事物碼裡的 ABAP Editor
- 在 Excel 內使用 ODBC 消費 SAP ABAP CDS viewExcelView
- SAP ABAP ADBC和Java JDBC的使用比較JavaJDBC
- SAP Cloud Application Programming 裡的@(path) 註解CloudAPP
- Spring(使用註解配置)Spring
- 在模擬器遊戲裡體驗另類“人生”遊戲
- Spring框架裡註解@Autowired的工作原理Spring框架
- SAP ABAP Netweaver裡的胖介面(fat interface)
- 使用Java JUnit框架裡的@Rule註解的用法舉例Java框架
- 【Spring註解驅動開發】在@Import註解中使用ImportBeanDefinitionRegistrar向容器中註冊beanSpringImportBean
- 在遊戲裡模擬天空的顏色,太迷人了!遊戲
- spring下應用@Resource, @Autowired 和 @Inject註解進行依賴注入的差異Spring依賴注入
- Java註解的使用Java
- 如何使用 ABAP 程式消費 SAP ABAP OData 服務
- Spring的@PropertySource註解使用Spring
- spring @profile註解的使用Spring
- 使用Java JUnit框架裡的@SuiteClasses註解管理測試用例Java框架UI
- 【Spring註解驅動開發】在@Import註解中使用ImportSelector介面匯入beanSpringImportBean
- SAP ABAP裡資料庫表的Storage Parameters從哪裡來的資料庫
- 在Java中正確使用註釋Java
- 使用 SAP ABAP 程式碼生成 PDF 檔案,填充以業務資料並顯示在 SAPGUI 裡試讀版GUI
- 學會使用 SAP ABAP Application Log 在程式碼裡新增應用日誌記錄功能試讀版APP應用日誌
- Java Spring的 JavaConfig 註解JavaSpring
- SAP ABAP的CI/CD解決方案
- Java JUnit框架裡@Category註解的工作原理Java框架Go
- Spring MVC 常用註解的使用SpringMVC
- Spring中@Import註解的使用SpringImport
- Spring IOC 常用註解與使用Spring