"Java knowledge application" Java CGLib using dynamic proxies and Rationale

A, CGLib jar package download

Baidu network disk:

Links: https://pan.baidu.com/s/1O_5o_vtPWEZ3Hy0CHlZDug
extraction code: 5wf6

CGLib also need to use additional asm.jar

Links: https://pan.baidu.com/s/1874lFlpOLsdzPUs7O9Ol-g
extraction code: wf68 

Two, CGLib Applications

package demo.knowledgepoints.cglib;

public class BaseDemo {

    private String Name;

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    @Override
    public String toString() {
        return "BaseDemo{" +
                "Name='" + Name + '\'' +
                '}';
    }
}
package demo.knowledgepoints.cglib;

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class MyMethodInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("=============执行自己想要的内容start================");
        System.out.println("method.getName():" + method.getName());
        Object object =methodProxy.invokeSuper (O, Objects); 
        System.out.println ( "============= perform their desired content end ============== == " );
         return Object; 
    } 
}
Package demo.knowledgepoints.cglib; 

Import net.sf.cglib.core.DebuggingClassWriter;
 Import the net.sf.cglib.proxy.Enhancer; 

public  class CGLibTest { 

    public  static  void main (String [] args) { 
        System.setProperty (DebuggingClassWriter. DEBUG_LOCATION_PROPERTY, "Demo src \\ \\ \\ knowledgepoints CGLIB" ); 

        / ** 
         * This class is set to CGLib dynamic proxy core, how you set up a kind of dynamic proxy 
         * / 
        Enhancer Enhancer = new new Enhancer ();
         / * * ***** proxy class to be provided ************* * / 
        enhancer.setSuperclass (BaseDemo. class );
        / ** ***** Set proxy class ************* * / 
        enhancer.setCallback ( new new MyMethodInterceptor ());
         / ** ***** create a proxy class *** ********** * / 
        BaseDemo proxyBaseDemo = (BaseDemo) enhancer.create (); 

        proxyBaseDemo.setName ( "Lei" ); 

    } 
}

operation result:

Here there will be a more interesting case, if it is run as follows dubug print information will appear

Simple explanation: because under IDEA duebug, you will need to query information, and this information is actually IDEA default toString method calls your object. toString IDEA execution, of course, is also the agent.

Three, CGLib principle of dynamic proxies

CGLib great dynamic proxy principle and the principle of dynamic JDK essential difference.

CGLib dynamic proxy principle: dynamic proxy is achieved by subclass inherits. The above applications we have CGLib proxy class generated locally:

We can look inside the decompiled code.

public class BaseDemo$$EnhancerByCGLIB$$3c73e677 extends BaseDemo implements Factory{
    final String CGLIB$toString$0() {
        return super.toString();
    }

    public final String toString() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (this.CGLIB$CALLBACK_0 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return var10000 != null ? (String)var10000.intercept(this, CGLIB$toString$0$Method, CGLIB$emptyArgs, CGLIB$toString$0$Proxy) : super.toString();
    }

    final String CGLIB$getName$1() {
        return super.getName();
    }

    public final String getName() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (this.CGLIB$CALLBACK_0 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return var10000 != null ? (String)var10000.intercept(this, CGLIB$getName$1$Method, CGLIB$emptyArgs, CGLIB$getName$1$Proxy) : super.getName();
    }

    final void CGLIB$setName$2(String var1) {
        super.setName(var1);
    }

    public final void setName(String var1) {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (this.CGLIB$CALLBACK_0 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        if (var10000 != null) {
            var10000.intercept(this, CGLIB$setName$2$Method, new Object[]{var1}, CGLIB$setName$2$Proxy);
        } else {
            super.setName(var1);
        }
    }
}

The code I took one of the more important information, real proxy class, but also some more code.

As can be seen from the contents of the file above:

1. inherited BaseDemo 

2. Implement Factory interface, which can create objects and other functions.

3. Rewrite the parent class method, and still call the original superclass method.

More use API methods, see CGLib: http://devdoc.net/javamisc/cglib-3.2.5/

Guess you like

Origin www.cnblogs.com/jssj/p/12635206.html