Today to introduce another more powerful agent--cglib dynamic agent.
What is a cglib dynamic agent?
Let's review the previous JDK dynamic agent, the JDK Dynamic agent is the interface to dynamically create the delegate class at runtime proxy object, but with the static proxy has a disadvantage, is the same interface must be implemented with the delegate class, when the number of interfaces increased, you need to increase the number of proxy classes to meet demand, And if the delegate class is written by someone else, and does not implement any interface, then the JDK dynamic agent is a bit too much.
At this time Cglib dynamic agents stand out, cglib do not rely on interfaces, you can directly generate the delegate class proxy object, and can delegate the class of arbitrary non-final modified public and protected method, we can first look at a chestnut.
Define a programmer class first:
Public class Programmer { private String name; Public void setName (String name) {
System.out.println ("Setting Name."); this. Name = name; } Public void code () { + "is writing bugs." ); }}
Then define a proxy class:
Public classProgrammerproxyImplementsMethodinterceptor {/*** Internal hold reference to delegate class object*/ PrivateObject Target; /*** Create proxy class object*/ PublicProgrammer Createproxy (Programmer object) {target=object; //Create a Enhancer objectEnhancer enhancer =Newenhancer (); //set the target class to be proxied to extend the functionalityEnhancer.setsuperclass ( This. Target.getclass ()); //set a single callback object to intercept calls to the target method in the callbackEnhancer.setcallback ( This); //set up the class loaderEnhancer.setclassloader (Object.getclass (). getClassLoader ()); //Create a proxy object return(Programmer) enhancer.create (); } /*** Callback method: Intercept and process the call of the target method on the proxy instance and return the result *@paramproxy class *@parammethod being proxied by *@paramparams array of parameters for this method *@paramMethodproxy*/@Override PublicObject Intercept (Object proxy, method, object[] params, methodproxy methodproxy)throwsThrowable {//called before processingDobefore (); //call the original methodMethod.invoke (Target,params); //processed after callDoafter (); return NULL; } Private voidDoafter () {System.out.println ("Do after."); } Private voidDobefore () {System.out.println ("Do before."); }}
Then test it:
Public classproxytest {@Test Public voidTestcglibproxy () {//Create a Programmer objectProgrammer Programmera =NewProgrammer (); Programmera.setname ("Frank"); //Create a proxy objectProgrammer Programmerproxya =Newprogrammerproxy (). Createproxy (Programmera); Programmerproxya.code (); //Modifying proxy objectsProgrammerproxya.setname ("Wang"); Programmerproxya.code (); //modifying delegate class objectsProgrammera.setname ("Song"); Programmerproxya.code (); }}
The output is as follows:
setting Name. do before. Frank is writing bugs. do after. do before. Setting Name. do after. do before. Wang is writing bugs. do after. Setting Name. do before. Song is writing bugs. do after.
Cglib the steps to implement a dynamic proxy are not cumbersome, first create a class implementation Methodinterceptor interface, override the Intercept method, and in intercep all non-final modified public and protected methods of the delegate class can be intercepted , in the example above, Method.invoke (Target,params), which is the same as the JDK dynamic proxy, where the reference to the delegate class object is saved in the proxy class for the original method of invoking the original object. The Dobefore method is called before the original method is called, and the Doafter method is called after the invocation, which implements the proxy function. As for the Createproxy method, it is just a fixed step, create the Enhance object first, then move some properties of the delegate class into the plug, and then call the Create method to dynamically generate the proxy object.
In the test class, in order to more clearly explain the relationship between the proxy class and the delegate class, the Name field is modified by the proxy class object Programmerproxya and the delegate class object Programmera, which can produce the same effect.
Here's a comparison of the Cglib dynamic Agent with the JDK Dynamic agent:
1. Both are dynamic proxies, which are dynamically generated proxy objects at run time.
2.JDK Dynamic Agent uses the interface information to implement the proxy, the delegate class must implement some or some interface, and Cglib is to use the inheritance relationship, using ASM to dynamically generate the subclass of the delegate class at run time, thus implementing the proxy class. Therefore, the interface is not dependent.
3.Cglib because an inheritance relationship is used to implement proxies, it is not possible to broker a final decorated class and a final decorated method.
4.Cglib is generally more efficient than JDK dynamic proxies and can be implemented with more powerful proxies.
Of course, specific analysis, although the cglib is more powerful than the JDK dynamic agent, but not necessarily all places are forced to use, sometimes the JDK dynamic agent is relatively simple and rough.
At this point, the end of this article, agent-related content explained, welcome to continue to pay attention to.
"Getting Started with Java" Day12 Java Agent--cglib dynamic agent