In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the relevant knowledge of "how to understand the static and dynamic agents of Java and SAP ABAP". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
The following figure shows a general implementation of the method in an application: the code for permission checking, logging, and performance testing has repeatedly intruded into three methods that should contain only business code:
The following figure shows the implementation of the method after applying AOP: the body of the three methods contains only pure business code, which looks much more refreshing. The code for permission checking, logging, and performance testing, as the three areas that still need to be concerned, is woven into the three methods in a faceted manner. The term in Weave,AOP, often translated as "weaving" in Chinese materials, describes the actions in which the methods of the proxied class are added with new logic through the non-source code modification level.
We say that object-oriented programming (Object Oriented Programming, referred to as OOP) is a concept, different programming languages can have different implementations. Similarly, there are different implementations of the concept of AOP in different programming languages.
The implementation of Java AOP can be divided into static proxy and dynamic proxy. Either way, in a nutshell, the core of AOP is that the business logic remains the same in the original class, while the woven non-business logic is in the proxy class. The code executed at run time is actually called the proxy class, and the business logic of the original class is invoked indirectly through the proxy class.
UML diagram of agent mode:
The way in which business logic is woven into the agent class during compilation is called static proxy; the way in which business logic is woven during operation is called dynamic proxy. To be exact, compile-time weaving can be subdivided into compile-time and post-compile weaving, while run-time knitting can be subdivided into load-time weaving and run-time knitting, but this subdivision method does not affect the following description of this article. therefore, it is only introduced in terms of compile time and run time.
Look at some specific examples.
Java static proxy
Define an interface for IDeveloper that contains a method for writeCode. Create a Developer class to implement the method.
Test: create a Developer instance named Jerry and call the writeCode method.
Suppose I want Developer to write the corresponding document before writing the code, but I don't want to invade the logic of writing the document into the writeCode method. Here, "writing documentation" is equivalent to non-business logic to be woven, or faceted logic to be woven.
Using the idea of static proxy, create another proxy class, DeveloperProxy:
Notice the writeCode method in the figure above. First, line 8 completes the task of writing the document, and then the proxy class calls the writeCode method of the proxy class Developer on line 9 to complete the actual business logic of writing the code.
Test the code:
Both Developer and DeveloperProxy implement the same interface IDeveloper, which is completely unaware and unnecessary for consumer code to perceive the internal differences between the two interface implementation classes-all completely transparent to consumer code. The consumer gets the introduction, points to a variable of type IDeveloper interface, and then calls the writeCode method defined on the interface.
Advantages and disadvantages of static agents
As can be seen from the above examples, the cornerstone of static proxy work is the interface. If, for some reason, the original class cannot be transformed into an implementation class of an interface (for example, the original class comes from legacy code of the system and cannot be refactored), static proxying will not work.
For each original class, using a static proxy, you need to create a proxy class with persistent storage. This approach is easy to understand, and the non-business logic (the "write document" behavior in the previous example) embeds static proxy classes during compilation, resulting in better runtime performance than the dynamic proxies to be introduced.
If you don't want to create a static proxy class manually in Java, you can use the tool AspectJ to do it automatically. Since the readers of this article are mainly ABAP developers, I will skip its usage here.
Automatic creation of ABAP static proxy class
I copied the idea of Java AspectJ and wrote a similar prototype in ABAP. Here is how to use it.
First I create a class CL_HELLOWORLD:
I want to automatically create a static proxy for this class. In the PRINT method of the proxy class, in addition to calling the PRINT method of the original class, do some extra logic, such as printing some output.
Calling the GET_PROXY method in the following figure automatically creates a static proxy class for CL_HELLOWORLD, weaving the additional logic specified in lines 7 and 8 into the PRINT method of the static proxy class:
Test: call the PRINT method of the static proxy class to get the output of the following figure. Two lines of WRITE statements woven into the static proxy class can be observed, which are called before and after the original class PRINT method respectively:
SE24 can observe the ABAP static classes that are automatically created by the tool I wrote, and the extra logic woven into the proxy class method PRINT:
The core of this tool is to call ABAP Class API to generate a new ABAP class, and the source code is available in the link provided by Jerry at the end of the article:
Dynamic proxy of Spring AOP
The so-called dynamic proxy, that is, the AOP framework will not do any processing to the original class during the compilation time, but until the application runs, it temporarily generates an AOP object in memory for the class that needs to be proxied, which contains all the methods of the original class, and makes enhancements at the proxied methods, weaves new logic, and calls back the methods of the original class.
There are two ways to implement Spring AOP dynamic agent: JDK dynamic agent and CGLIB dynamic agent.
JDK dynamic agent
The principle of JDK dynamic proxy is a method interceptor mechanism based on Java reflection mechanism.
Based on the first example, we add a new ITester interface to represent the position of tester:
The requirement now is to inject documentation logic into the tester's doTesting method. If we use a static proxy approach, we have to create another static proxy class for TesterProxy. With the increase in the number of job types in the development team, so does the number of these static agent classes.
So how to avoid this problem gracefully with dynamic proxies?
Create a new proxy class, named EnginnerProxy, which implies that the class that implements the JDK standard interface InnovationHandler can uniformly proxy the engineer class of all roles in a software development team at run time.
The bind method in the seventh line receives an instance of the proxy class and dynamically creates a temporary instance of the proxy class for that instance at run time. The so-called temporary means that the life cycle of the proxy instance only exists in the current session and is destroyed after the application is run, and will not be persisted like the static proxy class.
Once the method of the runtime class is executed, either the writeCode of Developer or the doTesting method of Tester will be intercepted by the invoke method of EnginnerProxy, uniformly execute the documentation logic of line 17 within the invoke method, and then call the original class method of line 18 that contains the business logic.
The following figure shows the test code and the results of the test. Now both Developer and Tester automatically perform documentation tasks before writing code and doing tests:
Advantages and disadvantages of dynamic Agent based on JDK
Obviously, when you need to proxy multiple classes, a dynamic proxy only needs to create a unified proxy class, rather than creating a separate proxy class for each class that contains business logic, as static proxies do. On the other hand, the agent class is "burned after use", which also avoids generating too many proxy classes in the project folder.
On the other hand, because dynamic proxies are implemented through the Java reflection mechanism at run time, runtime performance is worse than static proxies that do agent logic weaving during compilation. In addition, the prerequisites for JDK dynamic proxies to work are the same as static proxies, and the proxied class also needs to implement an interface.
Looking at a counterexample, assume that the product manager class ProductOwner does not implement any interfaces:
Using the JDK dynamic proxy, a ClassCastException exception is thrown at run time:
Because of the limitation of JDK dynamic agent, there is another way to realize dynamic agent: dynamic agent based on CGLIB.
CGLIB (Code Generation Library) is a Java bytecode generation library, which can process and enhance the bytecode of Java class at run time. The underlying implementation is based on the bytecode processing framework ASM.
CGLIB-based dynamic proxies can bypass the limitations of JDK dynamic proxies, even if a class that needs to be proxied does not implement any interface, it can also use CGLIB dynamic proxies.
Note that using the unified proxy class created by CGLIB this time, the imported development package comes from net.sf.cglib.proxy, not java.lang.reflect in the JDK dynamic proxy solution:
The style of consumer code is similar to that of JDK dynamic proxies:
Advantages and disadvantages of CGLIB dynamic Agent
CGLIB overcomes the limitation that the JDK dynamic proxy requires that the proxied class must implement an interface to work, but it also has its own limitations. CGLIB is essentially the way the runtime manipulates the bytecode of the Java class with API, directly creating a subclass that inherits from the proxied class, and then weaving aspect logic into this subclass method. Obviously, CGLIB dynamic proxies will not work if the proxied class is defined as uninheritable, such as modified by the final keyword in Java and ABAP.
To do a test, I mark the ProductOwner class as final, that is, it cannot be inherited, and the test code before running will encounter an exception and error message: Cannot subclass final class
ABAP dynamic agent
Because ABAP can not accurately achieve the effect of using one proxy class to intercept multiple methods executed by proxy class as Java JDK InnovationHandler does at the language level, Jerry chooses to simulate another dynamic proxy, that is, CGLIB proxy, with ABAP.
First create a class that needs to be proxied, and the business logic is written in the GREET method.
Then use the ABAP CGLIB utility class implemented by Jerry itself, get the proxy class of this class through its method GET_PPROXY, and call the GREET method of the proxy class:
Lines 8 and 9 above are classes that contain two faceted logic, and I expect their methods to be executed before and after being called by the GREET of the proxy class, respectively.
The core of ABAP CGLIB is in the generate_proxy method in the GET_PROXY method:
Here, the keyword GENERATE SUBROUTINE POOL of the ABAP dynamically generated class is used to generate a new temporary class according to the pre-pieced source code contained in the inner table mt_source. This class is not stored in SE24 or SE80, but only in the session of the current application.
After the 17 action generates a new proxy class, line 21 generates an instance of the proxy class, and then populates the aspect logic on lines 23 and 26, respectively.
Finally, call the GREET method of the proxy class instance, and the printout is as follows:
Where Hello World is the output of the GREET method of the original proxy class, that is, ZCL_JAVA_CGLIB, and its front and back behaviors call the aspect logic passed in when ABAP CGLIB generates the proxy class.
Up to now, although we realize that both static agents and dynamic agents have some defects, the reasons for these defects remind us once again that when writing new code, we should try our best to program for interfaces and avoid direct implementation-oriented programming, so as to reduce the coupling of programs and improve the maintainability, reusability and expansibility of applications.
The ABAP CGLIB tool described above is only a prototype developed by Jerry. In ABAP, if you only want to completely separate the aspect logic (such as permission checking, logging, performance analysis) from the business logic, you can use the standard ways to enhance the class methods provided by ABAP Netweaver: Pre-Exit and Post-Exit.
Select the class you want to enhance and click the Enhance menu:
This enhancement is stored separately from the proxied class:
Create a new Pre-Exit:
Click on the Pre-Exit panel and you can go in and write the code:
At run time, the code in Pre-Exit automatically triggers before being executed by the GREET method of the proxy class ZCL_JAVA_CGLIB:
When Jerry was working on the SAP Business By Design product before, he realized a lot of customer requirements with this Exit technology without modifying the product standard code. A typical customer requirement is to add extension fields to the SAP standard UI, whose values are calculated by complex logic in the background. So we first enhance the Response structure of the background API to create a new extension field, and then create a Post-Exit for the background API fetch method to implement the filling logic of the extension field in the Exit.
Although the use of Pre and Post-Exit is different from the way Java Spring AOP works based on annotations (Annotation), in effect, it can also achieve the requirement of Spring AOP to strictly separate business logic from non-business logic.
This is the end of the content of "how to understand static and dynamic proxies of Java and SAP ABAP". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.