First, dynamic agent Overview:
Comparison with static agents (for a description of static agents you can read the previous article: "Proxy pattern" in Java design mode),
The bytecode of a dynamic proxy class is generated dynamically by the Java reflection mechanism when the program is run.
Note:
1, ASPECTJ is the use of compile-time generation of AOP proxy class, with better performance, but need to use a specific compiler for processing
2. Spring AOP uses runtime to generate an AOP proxy class that does not need to be handled with a specific compiler, but with poor performance relative to AspectJ
Ii.JDK Dynamic Agent [ Proxy for objects that implement interfaces ]
1. Two important classes or interfaces that need to be understood in the JDK dynamic Agent [Invocationhandler and proxy]
①invocationhandler interface
Public interface Invocationhandler {
Parameter description:
Object proxy: Refers to the objects being proxied
Method Method: We are going to invoke the methods object of one of the proxy objects
object[] args: Parameters required by a method invocation of a proxy object
The subclass of the Invocationhandler interface can be imagined as the final action class of a proxy.
Note : Each dynamic proxy class must implement the Invocationhandler interface, and each instance of the proxy class is associated to a handler, when we call a method through the proxy object, The invocation of this method is forwarded to the Invoke method of this interface by Invocationhandler. At the same time, in the Invoke method we can enhance the method call of the proxy object (such as adding transaction, log, permission authentication and so on).
②proxy class
The proxy class is an action class that specifically completes the proxy, which can be used to dynamically generate implementation classes for one or more interfaces, which are commonly called as follows:
The Newproxyinstance method parameters are described below:
ClassLoader Loader: Class loader, which defines which ClassLoader object to load on the generated proxy object
class<?>[] Interfaces: Get the entire interface of the proxy class, if I provide a set of interfaces to it, then the proxy object declares that the interface is implemented, so I can invoke the methods in this set of interfaces.
invocationhandler H: Get subclass instance of Invocationhandler interface
2. JDK Dynamic Proxy code example:
First we define an interface of the Subject type: Subject.java
Public interface Subject {public void visit ();}
Next, define an implementation class for the interface, which is the proxy object in our example: Realsubject.java
/** * proxy class * @author [email protected] * */public class Realsubject implements Subject {@Overridepublic void visit () {
system.out.println ("I am ' realsubject ', I am the execution method");}}
The third step defines a dynamic proxy class (which must be implemented Invocationhandler this interface): Dynamicproxy.java
Import Java.lang.reflect.invocationhandler;import java.lang.reflect.method;/** * JDK Dynamic proxy class * @author [email protected] * */public class Dynamicproxy implements Invocationhandler {//We want to proxy the real object (delegate object) Private object subject;//construction method, Give us the actual object of the agent to assign the initial value public Dynamicproxy (Object obj) {this.subject = obj;} @Overridepublic object Invoke (Object object, method method, object[] args) throws Throwable {//We can add some of our own operations before acting on the real object operation Sy Stem.out.println ("Before proxy invoke"); When a proxy object invokes a method of a real object, it automatically jumps to the Invoke method of the handler object associated with the proxy object to invoke Method.invoke ( Subject, args);//After acting on the actual object operation we can add some of our own operation System.out.println ("After proxy invoke"); return null;}}
Last Agent Test class: Client.java
Import Java.lang.reflect.invocationhandler;import Java.lang.reflect.proxy;public class Client {public static void main (string[] args) {//We want to proxy the real object subject Realsubject = new Realsubject ();//We want to proxy which real object, the object is passed in, and finally through the real object calls the method of Invocationhandler Handler = new Dynamicproxy (realsubject);/* * Dynamically create our proxy object through the Newproxyinstance method of proxy, let's take a look at its three parameters <br/> * Parameter one: Here we use the ClassLoader object of the handler class to load our proxy object <br/> * Parameter two: the interface that we provide for the proxy object is the interface that the real object implements, which means that I want to represent the real object, So that I can invoke the methods in this set of interfaces <br/> * Parameter three: Here we associate this proxy object to the above Invocationhandler object */subject proxyinstance = (Subject) Proxy.newproxyinstance (Handler.getclass (). getClassLoader (), RealSubject.class.getInterfaces (), handler); System.out.println (Proxyinstance.getclass (). GetName ());p roxyinstance.visit ();}}
The results of the console output are as follows:
Com.sun.proxy. $Proxy 0before proxy invokei am ' realsubject ', I am the execution Methodafter proxy invoke
Third,Cglib (Code Generation Library) dynamic Agent [ for the ordinary class does not implement the interface Agent ]
1. Overview:
Cglib is an excellent dynamic proxy framework that uses ASM(Java bytecode Processing framework ) to dynamically generate subclasses of the proxy class in memory . Using Cglib can also implement dynamic proxy functionality even if the proxy class does not implement any interfaces. However, the final decorated class cannot be proxied.
2. Principle:
A subclass is created for a class by bytecode technology, and a method interception technique is used in subclasses to intercept calls to all parent methods.
<JDK Dynamic agent and Cglib dynamic Agent are fundamental to implement spring AOP >
3. Use:
The following two jar files need to be imported before using Cglib:
Asm.jar –cglib of the underlying implementation.
The bottom of the Cglib package is to use the bytecode processing framework ASM to convert bytecode and generate new classes, so the Cglib package relies on the ASM package "
Cglib.jar -Cglib's core jar package.
4. Cglib Dynamic Proxy code example:
First, define a proxy class that does not implement the interface: Cglibrealsubject.java
/** * No proxy classes implemented for interfaces * @author [email protected] * */public class cglibrealsubject{public void visit () {System.out.println (" I am ' realsubject ', I am the execution method ");}
thendefine a Cglib Dynamic proxy class: Cglibdynamicproxy.java
Import Java.lang.reflect.method;import Net.sf.cglib.proxy.enhancer;import net.sf.cglib.proxy.MethodInterceptor; Import net.sf.cglib.proxy.methodproxy;/** * Use cglib dynamic proxy * @author [email protected] * */public class Cglibdynamicproxy implements Methodinterceptor {Private Object target;/** * Create proxy Object * @param target object being proxied * @return */publ The IC object Getproxyinstance (object target) {This.target = target;//declares the enhanced class instance enhancer enhancer = new enhancer ();//sets the byte code of the proxy class, The cglib generates the subclass Enhancer.setsuperclass (This.target.getClass ()) of the proxy class based on the byte code; Set the interceptor to be proxied, the callback function, that is, a method to intercept new Methodinterceptor () Enhancer.setcallback (this); Create a Proxy object instance return enhancer.create (); } @Overridepublic Object Intercept (Object obj, Method method, object[] Args,methodproxy proxy) throws Throwable {//in Proxy real object We can add some of our own operations before Operation System.out.println ("pre-agent, enhanced processing");p roxy.invokesuper (obj, args);//After proxy real object operation We can also add some of our own operation System.out.println ("Post agent, enhanced processing"); return null;}}
Finally, test the client class:cglibclient. Java
public class Cglibclient {public static void main (string[] args) {cglibdynamicproxy cglib = new Cglibdynamicproxy (); Cglibrealsubject Realsubject = (cglibrealsubject) cglib.getproxyinstance (New Cglibrealsubject ()); RealSubject.visit ( );}}
The results of the console output are as follows:
Pre-agent, enhanced processing I am ' realsubject ', I am the execution method post agent, enhanced processing
Iv. Expansion of Learning
about what is AOP thinking? Spring AOP Implementation principle? And what kind of system business scenario can we use with this dynamic agent technology for AOP?
Xiao LV recommends an article that is worth reading and learning: Spring AOP Implementation principles and CGLIB applications
—————————————————————————————————————
if the content of the article is helpful to you, do not forget to support it by the top!
If you have any questions about the content of the article or have a better opinion, you can contact me by commenting or sending a message:
[Email protected]
If you need to reprint, please indicate the source, thank you!!
—————————————————————————————————————
Java Advanced JDK Dynamic agent and Cglib dynamic agent