Introduction to the use of three proxy frameworks

Source: Internet
Author: User
Tags throwable

Due to system architecture changes, agent technology needs to be used. Studied the Java commonly used 3 kinds of proxy way, here does the summary which uses. The following is a brief introduction to JDK, Cglib, Javaassit, respectively. The ASM is missing here because ASM is more complex to use and has very few scenes to use. JDK

The advantage of using JDK Proxy is that it is Java-self-contained and no longer relies on any third-party jar packages. The downside is that it can only act as an agent for the interface.

Class Injectproxy implements Invocationhandler {

    private Object target;

    Private Injectproxy (Object target) {
        this.target = target;
    }

    public object invoke (object proxy, Method method, object[] args) throws throwable{return

        Method.invoke (target, args) ;

    }

}

Invocationhandler ih = new Injectproxy (target);
ClassLoader ClassLoader = InjectProxy.class.getClassLoader ();
Return Proxy.newproxyinstance (ClassLoader, Target.getclass (). Getinterfaces (), IH);
Cglib

Cglib is familiar, it encapsulates the ASM complex interface and is simpler to use.
Cglib consists of 4 concepts, beangenerator, enhancer, Methodinterceptor, Lazyloader, and Dispatcher. Beangenerator

Beangenerator is mainly used to dynamically generate a subclass of a class, you can dynamically add some member variables to the subclass, automatically generate getter, setter method. The disadvantage is that it can only generate subclasses that contain default constructors.

Beangenerator Gen = Beangenerator ();
Gen.setsuperclass (superclass.class);
Gen.addproperty ("name", String.class);
Class Subclazz = (Class) Gen.createclass ();
Superclass obj = (superclass) gen.create ();
Enhancer

Enhancer an AOP feature used to implement a method invocation. Enhancer generated objects will contain many properties that are automatically added to the Cglib, so the resulting object will be relatively large. Methodinterceptor

public class Methodinterceptorimpl implements methodinterceptor{
    @Override the Public
    object intercept (Object obj , method method, object[] args, Methodproxy proxy) throws Throwable {return
            proxy.invokesuper (obj, args);
}

//proxy Invoke method
Enhancer enhancer = new enhancer ();
Enhancer.setsuperclass (clazz);
Enhancer.setcallbacks (New callback[]{noop.instance, New Methodinterceptorimpl ());
Enhancer.setcallbackfilter (New Callbackfilter () {
    @Override public
    int Accept (method method) {
        // Intercepts only the Invoke method of the algorithm interface definition
        if (method.getname (). Equals ("Invoke")) return
            1;
        return 0;
    }
});
Enhancer.setusefactory (false);
New Objects Object
proxy = Enhancer.create ();
Lazyloader

Lazyloader is the CGLIB proxy delay initialization interface. When an interface method is called for the first time, the object actually to be accessed is determined. What do you mean. Look at the code

public class Concreteclasslazyloader implements lazyloader{public class Propertybean {private String proper  
        Tyname;
        Public String Getpropertyname () {return propertyname;
        } public void Setpropertyname (String propertyname) {this.propertyname = propertyname; @Override public Object Loadobject () throws Exception {System.out.println ("Lazyloader loadobje  
        CT () ... ");  
        Propertybean bean=new Propertybean ();  
        Bean.setpropertyname ("Lazy-load object propertyname!");  
    return bean;  
        public static void Main (string[] args) {enhancer enhancer=new enhancer ();  
        Enhancer.setsuperclass (Propertybean.class);  

        Propertybean Propertybean = (Propertybean) enhancer.create (propertybean.class,new concreteclasslazyloader ());

        The Loadobject System.out.println (Propertybean.getpropertyname ()) is recalled here;  System.out.println ("After ...");
        After the LOADOBEJCT is no longer callback, direct access to the object System.out.println (Propertybean.getpropertyname ()) is returned for the first time. }
}
Dispatcher

The dispatcher function is the same as Lazyloader, except that dispatcher is recalled every time.

public class Concretedispatcher implements dispatcher{public class Propertybean {private String Propertynam  
        E
        Public String Getpropertyname () {return propertyname;
        } public void Setpropertyname (String propertyname) {this.propertyname = propertyname; @Override public Object Loadobject () throws Exception {System.out.println ("Dispatcher loadobje  
        CT () ... ");  
        Propertybean bean=new Propertybean ();  
        Bean.setpropertyname ("Dispatcher object propertyname!");  
    return bean;  
        public static void Main (string[] args) {enhancer enhancer=new enhancer ();  
        Enhancer.setsuperclass (Propertybean.class);  

        Propertybean Propertybean = (Propertybean) enhancer.create (propertybean.class,new concretedispatcher ());

        The Loadobject System.out.println (Propertybean.getpropertyname ()) is recalled here;  
        System.out.println ("After ...");Each time callback Loadobejct System.out.println (Propertybean.getpropertyname ()); }
}
Cglib Summary

Beangenerator suitable for subclass plus member variables
Methodinterceptor is a good way to intercept.
Lazyloader and dispatcher are suitable for object routing javaassist

Javaassist use less than cglib, because it is more difficult to use than cglib, can be dynamically splicing source to generate objects is its strengths. Generating Subclasses

Protected Ctclass Createsubclass (class<?> clazz) throws Cannotcompileexception, Notfoundexception,

    classnotfoundexception{/*javassist generates subclasses with Needlog attributes */classpool pool = Classpool.getdefault ();
    String proxyclassname = clazz.getname () + "$LogAble";
    Ctclass cc = Pool.getornull (proxyclassname);
        if (cc = null) {cc = Pool.makeclass (proxyclassname);

        Cc.setmodifiers (Modifier.public);
        Parent class Ctclass superclass = Pool.getornull (Clazz.getname ());
        if (superclass = = null) superclass = Pool.makeclass (Clazz.getname ());

        Cc.setsuperclass (superclass);
        Constructor Ctclass Stringclass = Pool.get ("java.lang.String");
        ctclass[] Constructorparamclassarr = new Ctclass[]{stringclass}; Generate a half-class constructor Ctconstructor CTC = Ctnewconstructor.make (Constructorparamclassarr,null,ctnewconstructor.pass_param 
        S,null,null, CC);

        Cc.addconstructor (CTC); Interface AddInterface (CC, LogaoPfilter.class);
    Add Needlog Properties Addclassproperty (cc, "Needlog", Boolean.class);
/*javassist Method End */return CC; * * * Subclass ADD Interface * * protected void AddInterface (Ctclass cc, class<?> interfaceclass) {Classpool pool = Classpool
    . Getdefault ();
    Ctclass ccinterface = Pool.getornull (Interfaceclass.getname ());
    if (Ccinterface = = null) Ccinterface = Pool.makeinterface (Interfaceclass.getname ());
Cc.addinterface (Ccinterface); * * * Subclass Add Properties */protected void Addclassproperty (Ctclass cc, String name, class<?> type) throws Cannotcompileexce
ption{Addclassproperty (CC, Name, type, "");} protected void Addclassproperty (Ctclass cc, string name, class<?> type, string decorate) throws Cannotcompileexcept
    ion{Ctfield field = Ctfield.make (String.Format ("private%s%s%s;", Decorate, Type.getname (), name), CC);
    Cc.addfield (field); Ctmethod GetMethod = Ctmethod.make (String.Format ("Public%s get%s () {return%s;}", Type.getname(), name.substring (0, 1). toUpperCase () + name.substring (1), name), CC);
    Cc.addmethod (GetMethod); Ctmethod Setmethod = Ctmethod.make (String.Format ("public void set%s (%s value) {this.%s = $1;return;}", Name.substring (0,  
    1). toUpperCase () + name.substring (1), Type.getname (), name), CC);
Cc.addmethod (Setmethod); }
build Agent

Javaassit the process of generating proxy objects is similar to Cglib.

Private class Methodhandlerimpl implements Methodhandler {

    final Object delegate;

    Methodhandlerimpl (Object delegate) {
        this.delegate = delegate;
    }

    Public Object invoke (Object Self, Method M, method proceed, object[] args) throws Throwable {return
        M.invoke (delegate , args);
    }

Proxyfactory proxyfactory = new Proxyfactory ();
Proxyfactory.setsuperclass (superclass.class);
Proxyfactory.setinterfaces (new class[] {superinterface.class});
class<?> Proxyclass = Proxyfactory.createclass ();
Superinterface proxy = (superinterface) proxyclass.newinstance ();
((proxyobject) proxy). SetHandler (New Methodhandlerimpl (delegate));
Performance Comparison

There are a lot of performance tests for proxy objects generated by three frameworks, which can be referenced in this article.

Basically the order is
Javaassit stitching source Generation method (5 times times) > Cglib Methodinterceptor generated method (twice times) > JDK proxy generation > Javaassist metho Dinterceptor the generated method.

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.