SAP ABAP CGLIB(Code Generation Library)的模擬實現
What is CGLIB?
A Byte Code Generation Library which is high level API to generate and transform Java byte code. It is used in various scenarios such as AOP, testing, data access frameworks to generate dynamic proxy objects and intercept field access.
See one example in unit test.
In line 17, a new dynamic proxy class is generated as mock. In line 19, we tell the proxy, “if get(0) is called on this mock class, then return mocked data “hello, world”. As a result, in line 23 “result: hello, world” will be printed out.
In debugger you can find that the variable in line 17 is mocked by CGLIB:
Its byte code is generated dynamically and stored in variable byte[] b in line 217.
Let’s see another example of injecting pre-exit and post-exit ( which ABAPers are very familiar with ) into a given method via dynamic proxy generated by CGLIB:
(1) I have a class MyMEthodExitDemo which has a normal method myFun. (2) A new dynamic proxy class is generated in method createProxy which has a method with equal name as original class plus custom enhancement covered by class JerryEnhancement.
(3) The pre-exit and post-exit are defined in class JerryEnhancement which implements interface MethodInterceptor defined in CGLIB library. The original method is generated in line 14, with pre-exit before it ( line 13 ) and post-exit after it ( line 15 ).
Execute result:
How does this example work under the hood?
I implement a demo in ABAP with the same logic.
(1) I have a very simple ABAP class with only one public method which will print “Hello World”:
(2) The CGLIB utility class in line 5 simulates the logic in Java, which will construct a proxy class based on existing global class ZCL_JAVA_CGLIB. The generated proxy class will be DYNAMICALLY injected with two enhancement implemented by zcl_jerry_preexit and zcl_jerry_postexit.
There are two interfaces defined for pre-exit and post-exit logics which contain only one EXECUTE method without any parameters:
And zcl_jerry_preexit and zcl_jerry_postexit implement these two interfaces accordingly:
once method greet in line 16 is called, the enhanced version of method greet is called:
By this way, the method greet is enhanced in a non-invasive approach – no modification on original class, no new class are persisted in repository.
The method get_proxy of zcl_abap_cglib_tool does the magic, I just follow the idea of CGLIB implementation in Java:
The pre-exit and post-exit passed by consumer are dynamically injected into proxy class here:
Till now you should be familiar with CGLIB idea, and it is quite easy to understand why it is NOT possible to create a proxy class based on a final class by CGLIB, simply because a final class could not be subclassed.
The report to consume it:
REPORT zcglib_proxy_generate.DATA: lo_proxy TYPE REF TO object.CALL METHOD zcl_abap_cglib_tool=>get_proxy
EXPORTING
iv_class_name = 'ZCL_JAVA_CGLIB'
io_pre_exit = NEW zcl_jerry_preexit( )
io_post_exit = NEW zcl_jerry_postexit( )
RECEIVING
ro_proxy = lo_proxy.CHECK lo_proxy IS NOT INITIAL.DATA(lo_class) = CAST zcl_java_cglib( lo_proxy ).lo_class->greet( ).
Update on 2017-02-02 CGLIB use scenario
The CGLIB is widely used in many Java framework, for example Mockito as a unit test framework. See my another blog Simulate Mockito in ABAP for detail.
要獲取更多Jerry的原創文章,請關注公眾號"汪子熙":
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24475491/viewspace-2713820/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Java的Covariance設計原理和SAP ABAP的模擬實現Java
- Implement CGLIB in ABAPCGLib
- SAP ABAP Gateway Client 的 ABAP 實現,重用 HTTP ConnectionGatewayclientHTTP
- 在SAP ABAP裡使用註解@Inject模擬Java SpringJavaSpring
- SAP ABAP和Java的動態代理實現Java
- SAP ABAP OData 服務的 $count 操作實現
- promise的模擬實現Promise
- javascript模擬new的實現JavaScript
- JavaScript 模擬new的實現JavaScript
- ent orm筆記4---Code GenerationORM筆記
- SAP ABAP關鍵字語法圖和ABAP程式碼自動生成工具Code Composer
- strlen函式的模擬實現函式
- 淺談 SAP ABAP 系統裡的 ALV 輸出方式實現
- SAP ABAP應用伺服器的HTTP響應狀態碼(Status Code)伺服器HTTP
- Fundamental Library for ABAP 主要的組成部分概述
- Laravel-Gii Visual code generation tool CRUD + GUILaravelGUI
- qsort的模擬實現和練習
- 模擬實現apply/call/bindAPP
- JavaScript模擬實現replaceAll方法JavaScript
- bind,call,apply模擬實現APP
- JavaScript中模擬實現jsonpJavaScriptJSON
- 【Java】——模擬登入實現Java
- SAP UI5 Cross Application Navigation (跨應用間跳轉)的本地模擬實現UIROSAPPNavigation
- SAP ABAP Netweaver 裡的 ABAP 會話概念會話
- 一些 Next Generation ABAP Platform 的新語法用例Platform
- 用一個div模擬textarea的實現
- SAP 長期模擬計劃
- 實戰模擬│單點登入 SSO 的實現
- bind/new/instanceof/assign模擬實現
- 模擬實現簡易版shell
- CGLib動態代理原理及實現CGLib
- 用ABAP模擬JavaScript的柯里化語言特性(Curry)JavaScript
- SAP ABAP FOR ALL ENTRIES 的用法
- 三維模擬模擬如何實現精益工廠佈局?
- JavaScript 深入之 call 和 apply 的模擬實現JavaScriptAPP
- 詳解 new/bind/apply/call 的模擬實現APP
- c++實現的模擬退火演算法C++演算法
- Web 魔方模擬器的設計與實現Web