Deep analysis of dynamic agents

Source: Internet
Author: User

Dynamic proxies are dynamically generated proxy classes at run time. The byte code of the proxy class is generated at run time and loaded into the current ClassLoader.

There are many ways to generate dynamic proxy classes, such as The dynamic agent that comes with the JDK,CGLIB,Javassist , or ASM Library.

JDKDynamic Proxy is simple to use and it is built intoJDKand therefore does not require the introduction of third-partyJarpackage, but relative functionality is weak. CGLIBand theJavassistare high-level bytecode generation libraries with overall performance ratiosJDKthe self-brought dynamic agent is good, and the function is very powerful. ASMis a low-level bytecode generation tool that usesASMis almost in useJavabytecodeprogramming, high demand for developers, is also the best performance of a dynamic agent birthday tool. ButASMuse is too cumbersome, and performance is not an order of magnitude improvement, withCGLIBWhen compared to the advanced bytecode generation tool,ASMThe program is also poorly maintainable.


JDK Implementation

1. Steps

1 ) by implementing Invocationhandler interface to create its own calling processor

2 ) by providing Proxy class specifies ClassLoader objects and a set of Interface to create a dynamic proxy class

3 The constructor of the dynamic proxy class is obtained through the reflection mechanism, and its unique parameter type is the calling processor interface type

4 creates a dynamic proxy class instance through a constructor that constructs a call to the processor object as a parameter is passed in


2. Create an agent

  Invocationhandlerimpl implements the Invocationhandler interface and can implement the dispatch and forwarding of method calls from the proxy class to the delegate class//its interior typically contains a reference to the delegate class instance. Method call Invocationhandler handler = new Invocaitonhandlerimpl (..) used to actually perform dispatch forwarding /proxy for a set of interfaces, including the Interface interface, to dynamically create the object class Clazz = Proxy.getproxyclass (Classloader,new class[]{interface.class, ...});/ /Get the constructor object from the generated class object by reflection        Constructor Constructor = clazz.getconstructor (New Class[]{invocationhandler.class});// Create a dynamic proxy class instance from a constructor object Interface proxy = (Interface) constructor.newinstance (New Object[]{handler});// The static method of the proxy class newproxyinstance the latter three steps of the above step, and simplifies the acquisition process of the dynamic proxy object. Invocationhandlerimpl implements the Invocaitonhandler interface and enables the dispatch and forwarding of method calls from the proxy class to the delegate class Invocaitonhandler handler = new Invocationhandlerimpl (..); /Create a dynamic proxy class instance directly by proxy Interface proxy = (Interface) proxy.newproxyinstance (Classloader,new Class[]{interface.class}, handler);

3. Code

/** * Interface * @author Emily * */public interface Idbquery {String request ();} /** * Real implementation class, specific target object * @author Emily * */public class Dbquery implements Idbquery {public dbquery () {try {thread.sleep (1000 ); may contain time-consuming operations such as database connections} catch (Interruptedexception e) {e.printstacktrace ();}} @Overridepublic string Request () {return "Request String";}} /** * JDK Dynamic Proxy implementation class * @author Emily * */public class Jdkdbqueryhandler implements invocationhandler{idbquery real = null;// Theme Interface/** * Generate handler */@Overridepublic object Invoke (Object proxy, method, object[] args) throws Throwable {if (real = = null) Real = new Dbquery ();  If this is the first call, the real object return Real.request () is generated; Use real-world themes to do the actual work}/** * Generate dynamic proxy objects with handler * @return */public static idbquery Createjdkproxy () {///According to the specified class loader and interface and the Interceptor, Returns an instance object of the proxy class//classloader loader: Specifies the class loader of the Proxied object//class[] Interfaces: Specifies the interface to which the object is being proxied//invocationhandler h: Specifies the Invocationhandler object that needs to be called idbquery Jdkproxy = (idbquery) proxy.newproxyinstance (Classloader.getsystemclassloader () , New Class[]{idbquery.Class}, New Jdkdbqueryhandler ()); return jdkproxy;}} 

Cglib Implementation

Package Com.ltt.dynamic;import Java.lang.reflect.method;import Net.sf.cglib.proxy.enhancer;import Net.sf.cglib.proxy.methodinterceptor;import net.sf.cglib.proxy.methodproxy;/** * cglib Dynamic Agent * @author Emily * */public Class Cglibdbqueryinterceptor implements Methodinterceptor{idbquery real = null;/** * The cut-in class for processing proxy logic */@Overridepublic  Object Intercept (Object arg0, Method arg1, object[] arg2,methodproxy arg3) throws Throwable {if (real = null) {    //proxy class The internal logic real = new Dbquery (); return real.request ();} return null;} /** * Generate dynamic Agent * @return */public static idbquery createcglibproxy () {Enhancer enhancer = new enhancer ();//Specify the switch, define proxy class logic Enhan Cer.setcallback (New Cglibdbqueryinterceptor ());//Specifies the implemented interface enhancer.setinterfaces (new Class[]{idbquery.class}); Dbquery cglibproxy = (idbquery) enhancer.create (); return cglibproxy;}}


Javassist Implementation

One is created using a proxy factory, and the other is created by using dynamic code. When created with a proxy factory, the method is similar to Cglib and requires a handler that is used for proxy logic processing: createjavassistdynproxy (), using dynamic code creation to generate bytecode, which can be very flexible, You can even generate business logic, such as the Createjavassistbytecodedynamicproxy () method, at run time.

/** * javassist Dynamic Agent * @author Emily * */public class Javassistdyndbqueryhandler implements Methodhandler{idbquery real = n ull;/* * (Non-javadoc) implements handler * @see Javassist.util.proxy.methodhandler#invoke for Proxy logic processing (Java.lang.Object, Java.lang.reflect.Method, Java.lang.reflect.Method, java.lang.object[]) */@Overridepublic object Invoke (Object arg0, Method Arg1, Method Arg2, object[] arg3) throws Throwable {if (real = null) real = new Dbquery (); return real.request ();} /** * Create dynamic Agent * @return * @throws Exception */public static Idbquery Createjavassistdynproxy () throws Exception{proxyfactor  Y proxyfactory = new proxyfactory ();p roxyfactory.setinterfaces (New Class[]{idbquery.class}); Specifies the interface class Proxyclass = Proxyfactory.createclass (); Idbquery javassistproxy = (idbquery) proxyclass.newinstance (); Set the handler processor ((Proxyobject) javassistproxy). SetHandler (New Javassistdyndbqueryhandler ()); return javassistproxy;} /** * Runtime generates business logic * @return * @throws Exception */public static Idbquery CreatejavassistbyTecodedynamicproxy () throws Exception{classpool Mpool = new Classpool (true);//define class name Ctclass MCTC = Mpool.makeclass ( IDBQuery.class.getName () + "Javaassistbytecodeproxy");//need to Implement Interface Mctc.addinterface (Mpool.get (IDBQuery.class.getName ());//Add Constructor Mctc.addconstructor (Ctnewconstructor.defaultconstructor (MCTC));//Add field information for the class, use dynamic Java code Mctc.addfield (Ctfield.make ("public" + IDBQuery.class.getName () + "real;", MCTC)); String dbqueryname = DBQuery.class.getName ();//Add method, where dynamic Java code is used to specify the internal logic mctc.addmethod (Ctnewmethod.make ("public  String request () {if (real==null) real = new "+dbqueryname+" (); return real.request ();} ", MCTC));//based on the above information, generate the dynamic class Mctc.toclass ();//Generate instance of dynamic class idbquery Bytecodeproxy = (idbquery) pc.newinstance (); return bytecodeproxy;}}

Three types of dynamic agents:JDKdynamic proxy creation is faster thanCGLIBdynamic proxies, but not as much as the function's call performanceCGLIBand theJavassist. Therefore, the overall performance of Cglib and Javassist is better than the JDK dynamic agent.


Dynamic proxy VS static proxy

Static proxy

1) An interface of the proxy object only serves one type of object, if there are many methods to proxy, it is bound to proxy for each method, static agent is not competent when the program size is slightly larger.

2) If the interface adds a method, all the proxy classes need to implement this method in addition to implementing the method for all implementation classes. Increases the complexity of code maintenance.

Dynamic Agent

1 ) The source code of the dynamic proxy class is generated dynamically by the JVM based on the reflection mechanism during the program running , so there is no bytecode file for the proxy class. The relationship between the proxy class and the delegate class is determined when the program is run.

2 compared to static proxies, the biggest benefit is that all the methods declared in the interface are transferred to the calling processor in a centralized method for processing. In this way, when the number of interface methods is more, we can be flexible processing, and do not need to act as a static proxy for each method to relay.

3 dynamic proxies can significantly reduce the number of lines of code and increase the flexibility of the system.




Deep analysis of dynamic agents

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.