CGLib介绍

内容转自:http://www.blogjava.net/stone2083/archive/2008/03/16/186615.html

CGlib简单介绍

CGlib概述:
cglib( Code Generation Library )是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。
cglib封装了asm,可以在运行期动态生成新的class。
cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制。

CGlib应用:
以一个实例在简单介绍下cglib的应用。
我们模拟一个虚拟的场景,关于信息的管理。

1)原始需求是任何人可以操作信息的create,update,delete,query操作。
InfoManager.java --封装对信息的操作
public  class InfoManager {
     //  模拟查询操作
     public  void query() {
        System.out.println("query");
    }
     //  模拟创建操作
     public  void create() {
        System.out.println("create");
    }
     //  模拟更新操作
     public  void update() {
        System.out.println("update");
    }
     //  模拟删除操作
     public  void delete() {
        System.out.println("delete");
    }
}
InfoManagerFactory.java --工厂类
public  class InfoManagerFactory {
     private  static InfoManager manger =  new InfoManager();
     /**
     * 创建原始的InfoManager
     * 
     * 
@return
     
*/
     public  static InfoManager getInstance() {
         return manger;
    }
}
client.java --供客户端调用
public  class Client {

     public  static  void main(String[] args) {
        Client c =  new Client();
        c.anyonecanManager();
    }

     /**
     * 模拟:没有任何权限要求,任何人都可以操作
     
*/
     public  void anyonecanManager() {
        System.out.println("any one can do manager");
        InfoManager manager = InfoManagerFactory.getInstance();
        doCRUD(manager);
        separatorLine();
    }

     /**
     * 对Info做增加/更新/删除/查询操作
     * 
     * 
@param  manager
     
*/
     private  void doCRUD(InfoManager manager) {
        manager.create();
        manager.update();
        manager.delete();
        manager.query();
    }

     /**
     * 加一个分隔行,用于区分
     
*/
     private  void separatorLine() {
        System.out.println("################################");
    }

}
至此,没有涉及到cglib的内容,因为需求太简单了,但是接下来,需求发生了改变,要求:

2)只有一个叫“maurice”的用户登录,才允许对信息进行create,update,delete,query的操作。
怎么办?难道在每个方法前,都加上一个权限判断吗?这样重复逻辑太多了,于是乎想到了Proxy(代理模式),但是原先的InfoManager也没有实现接口,不能采用jdk的proxy。那么cglib在这边就要隆重登场。
一旦使用cgblig,只需要添加一个MethodInterceptor的类以及修改factory代码就可以实现这个需求。
AuthProxy.java --权限校验代理类
public  class AuthProxy  implements MethodInterceptor {

     private String name;  //  会员登录名

     public AuthProxy(String name) {
         this.name = name;
    }

     /**
     * 权限校验,如果会员名为:maurice,则有权限做操作,否则提示没有权限
     
*/
    @Override
     public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)  throws Throwable {
         if (!"maurice".equals( this.name)) {
            System.out.println("AuthProxy:you have no permits to do manager!");
             return  null;
        }
         return proxy.invokeSuper(obj, args);
    }

     public String getName() {
         return name;
    }

     public  void setName(String name) {
         this.name = name;
    }

}
InfoManagerFactory.java --代码变动如下:
public  class InfoManagerFactory {

     /**
     * 创建带有权限检验的InfoManager
     * 
     * 
@param  auth
     * 
@return
     
*/
     public  static InfoManager getAuthInstance(AuthProxy auth) {
        Enhancer enhancer =  new Enhancer();
        enhancer.setSuperclass(InfoManager. class);
        enhancer.setCallback(auth);
         return (InfoManager) enhancer.create();
    }

    
}
client.java --代码修改如下
public  class Client {

     public  static  void main(String[] args) {
        Client c =  new Client();
        c.haveNoAuthManager();
        c.haveAuthManager();
    }

     /**
     * 模拟:登录会员没有权限
     
*/
     public  void haveNoAuthManager() {
        System.out.println("the loginer's name is not maurice,so have no permits do manager ");
        InfoManager noAuthManager = InfoManagerFactory.getAuthInstance( new AuthProxy("maurice1"));
        doCRUD(noAuthManager);
        separatorLine();
    }

     /**
     * 模拟:登录会员有权限
     
*/
     public  void haveAuthManager() {
        System.out.println("the loginer's name is maurice,so have permits do manager ");
        InfoManager authManager = InfoManagerFactory.getAuthInstance( new AuthProxy("maurice"));
        doCRUD(authManager);
        separatorLine();
    }

     /**
     * 对Info做增加/更新/删除/查询操作
     * 
     * 
@param  manager
     
*/
     private  void doCRUD(InfoManager manager) {
        manager.create();
        manager.update();
        manager.delete();
        manager.query();
    }

     /**
     * 加一个分隔行,用于区分
     
*/
     private  void separatorLine() {
        System.out.println("################################");
    }

}
执行下代码,发现这时client端中已经加上了权限校验。
同样是InfoManager,为什么这时能多了权限的判断呢?Factory中 enhancer.create()返回的到底是什么对象呢?这个疑问将在第三部分CGlib中解释。
这边的代码,其实是介绍了cglib中的enhancer功能.

到这里,参照上面的代码,就可以使用cglib带来的aop功能了。但是为了更多介绍下cglib的功能,模拟需求再次发生变化:

3)由于query功能用户maurice才能使用,招来其他用户的强烈的抱怨,所以权限再次变更,只有create,update,delete,才需要权限保护,query任何人都可以使用。
怎么办?采用AuthProxy,使得InfoManager中的所有方法都被代理,加上了权限的判断。当然,最容易想到的办法,就是在AuthProxy的intercept的方法中再做下判断,如果代理的method是query,不需要权限验证。这么做,可以,但是一旦逻辑比较复杂的时候,intercept这个方法要做的事情会很多,逻辑会异常的复杂。
幸好,cglib还提供了CallbackFilter。使用CallbackFilter,可以明确表明,被代理的类(InfoManager)中不同的方法,被哪个拦截器(interceptor)拦截。
AuthProxyFilter.java
public  class AuthProxyFilter  implements CallbackFilter {

     private  static  final  int AUTH_NEED     = 0;
     private  static  final  int AUTH_NOT_NEED = 1;

     /**
     * <pre>
     * 选择使用的proxy
     * 如果调用query函数,则使用第二个proxy
     * 否则,使用第一个proxy
     * </pre>
     
*/
    @Override
     public  int accept(Method method) {
         if ("query".equals(method.getName())) {
             return AUTH_NOT_NEED;
        }
         return AUTH_NEED;
    }

}
这段代码什么意思?其中的accept方法的意思是说,如果代理的方法是query(),那么使用第二个拦截器去拦截,如果代理的方法不是query(),那么使用第一个拦截器去拦截。所以我们只要再写一个拦截器,不做权限校验就行了。(其实,cglib中的NoOp.INSTANCE就是一个空的拦截器,只要配置上这个就可以了。)
InfoManagerFactory.java --代码修改如下:(配置不同的拦截器和filter)
public  class InfoManagerFactory {

     /**
     * 创建不同权限要求的InfoManager
     * 
     * 
@param  auth
     * 
@return
     
*/
     public  static InfoManager getSelectivityAuthInstance(AuthProxy auth) {
        Enhancer enhancer =  new Enhancer();
        enhancer.setSuperclass(InfoManager. class);
        enhancer.setCallbacks( new Callback[] { auth, NoOp.INSTANCE });
        enhancer.setCallbackFilter( new AuthProxyFilter());
         return (InfoManager) enhancer.create();
    }

}
记住:setCallbacks中的拦截器(interceptor)的顺序,一定要和 CallbackFilter里面指定的顺序一致!!切忌。

Client.java
public  class Client {

     public  static  void main(String[] args) {
        Client c =  new Client();
        c.selectivityAuthManager();
    }
    
     /**
     * 模拟:没有权限的会员,可以作查询操作
     
*/
     public  void selectivityAuthManager() {
        System.out.println("the loginer's name is not maurice,so have no permits do manager except do query operator ");
        InfoManager authManager = InfoManagerFactory.getSelectivityAuthInstance( new AuthProxy("maurice1"));
        doCRUD(authManager);
        separatorLine();
    }

     /**
     * 对Info做增加/更新/删除/查询操作
     * 
     * 
@param  manager
     
*/
     private  void doCRUD(InfoManager manager) {
        manager.create();
        manager.update();
        manager.delete();
        manager.query();
    }

     /**
     * 加一个分隔行,用于区分
     
*/
     private  void separatorLine() {
        System.out.println("################################");
    }

}
此时,对于query的权限校验已经被去掉了。


通过一个模拟需求,简单介绍了cglib aop功能的使用。
CGlib应用非常广,在spring,hibernate等框架中,被大量的使用。


CGlib原理:
cglib神奇吗?其实一旦了解cglib enhancer的原理,一切就真相大白了。
刚才在第二部分中,有个疑问:enhancer.create()到底返回了什么对象?

其实在刚才的例子中,cglib在代码运行期,动态生成了InfoManager的子类,并且根据CallbackFilter的accept方法,覆写了InfoManager中的所有方法--去执行相应的MethodInterceptor的intercept方法。

有兴趣的朋友可以看看我反编译的InfoManager的子类,就可以很明白知道具体的实现了。(需要有耐心才可以)
InfoManager$$EnhancerByCGLIB$$de624598.jad
//  Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
//  Jad home page:  http://www.geocities.com/kpdus/jad.html
//  Decompiler options: packimports(3) 
//  Source File Name:   <generated>

package cn.eulic.codelab.cglib;

import java.lang.reflect.Method;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.*;

//  Referenced classes of package cn.eulic.codelab.cglib:
//             InfoManager

public  class CGLIB.BIND_CALLBACKS  extends InfoManager
     implements Factory
{

     static  void CGLIB$STATICHOOK1()
    {
        Class class1;
        ClassLoader classloader;
        CGLIB$THREAD_CALLBACKS =  new ThreadLocal();
        classloader = (class1 = Class.forName("cn.eulic.codelab.cglib.InfoManager$$EnhancerByCGLIB$$de624598")).getClassLoader();
        classloader;
        CGLIB$emptyArgs =  new Object[0];
        CGLIB$delete$0$Proxy = MethodProxy.create(classloader, (CGLIB$delete$0$Method = Class.forName("cn.eulic.codelab.cglib.InfoManager").getDeclaredMethod("delete",  new Class[0])).getDeclaringClass(), class1, "()V", "delete", "CGLIB$delete$0");
        CGLIB$create$1$Proxy = MethodProxy.create(classloader, (CGLIB$create$1$Method = Class.forName("cn.eulic.codelab.cglib.InfoManager").getDeclaredMethod("create",  new Class[0])).getDeclaringClass(), class1, "()V", "create", "CGLIB$create$1");
        CGLIB$query$2$Proxy = MethodProxy.create(classloader, (CGLIB$query$2$Method = Class.forName("cn.eulic.codelab.cglib.InfoManager").getDeclaredMethod("query",  new Class[0])).getDeclaringClass(), class1, "()V", "query", "CGLIB$query$2");
        CGLIB$update$3$Proxy = MethodProxy.create(classloader, (CGLIB$update$3$Method = Class.forName("cn.eulic.codelab.cglib.InfoManager").getDeclaredMethod("update",  new Class[0])).getDeclaringClass(), class1, "()V", "update", "CGLIB$update$3");
        CGLIB$finalize$4$Proxy = MethodProxy.create(classloader, (CGLIB$finalize$4$Method = Class.forName("java.lang.Object").getDeclaredMethod("finalize",  new Class[0])).getDeclaringClass(), class1, "()V", "finalize", "CGLIB$finalize$4");
        CGLIB$hashCode$5$Proxy = MethodProxy.create(classloader, (CGLIB$hashCode$5$Method = Class.forName("java.lang.Object").getDeclaredMethod("hashCode",  new Class[0])).getDeclaringClass(), class1, "()I", "hashCode", "CGLIB$hashCode$5");
        CGLIB$clone$6$Proxy = MethodProxy.create(classloader, (CGLIB$clone$6$Method = Class.forName("java.lang.Object").getDeclaredMethod("clone",  new Class[0])).getDeclaringClass(), class1, "()Ljava/lang/Object;", "clone", "CGLIB$clone$6");
        CGLIB$equals$7$Proxy = MethodProxy.create(classloader, (CGLIB$equals$7$Method = Class.forName("java.lang.Object").getDeclaredMethod("equals",  new Class[] {
            Class.forName("java.lang.Object")
        })).getDeclaringClass(), class1, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$7");
        CGLIB$toString$8$Proxy = MethodProxy.create(classloader, (CGLIB$toString$8$Method = Class.forName("java.lang.Object").getDeclaredMethod("toString",  new Class[0])).getDeclaringClass(), class1, "()Ljava/lang/String;", "toString", "CGLIB$toString$8");
         return;
    }

     final  void CGLIB$delete$0()
    {
         super.delete();
    }

     public  final  void delete()
    {
        CGLIB$CALLBACK_0;
         if(CGLIB$CALLBACK_0 !=  nullgoto _L2;  else  goto _L1
_L1:
        JVM INSTR pop ;
        CGLIB$BIND_CALLBACKS( this);
        CGLIB$CALLBACK_0;
_L2:
        JVM INSTR dup ;
        JVM INSTR ifnull 37;
            goto _L3 _L4
_L3:
         break MISSING_BLOCK_LABEL_21;
_L4:
         break MISSING_BLOCK_LABEL_37;
         this;
        CGLIB$delete$0$Method;
        CGLIB$emptyArgs;
        CGLIB$delete$0$Proxy;
        intercept();
         return;
         super.delete();
         return;
    }

     final  void CGLIB$create$1()
    {
         super.create();
    }

     public  final  void create()
    {
        CGLIB$CALLBACK_0;
         if(CGLIB$CALLBACK_0 !=  nullgoto _L2;  else  goto _L1
_L1:
        JVM INSTR pop ;
        CGLIB$BIND_CALLBACKS( this);
        CGLIB$CALLBACK_0;
_L2:
        JVM INSTR dup ;
        JVM INSTR ifnull 37;
            goto _L3 _L4
_L3:
         break MISSING_BLOCK_LABEL_21;
_L4:
         break MISSING_BLOCK_LABEL_37;
         this;
        CGLIB$create$1$Method;
        CGLIB$emptyArgs;
        CGLIB$create$1$Proxy;
        intercept();
         return;
         super.create();
         return;
    }

     final  void CGLIB$query$2()
    {
         super.query();
    }

     public  final  void query()
    {
        CGLIB$CALLBACK_0;
         if(CGLIB$CALLBACK_0 !=  nullgoto _L2;  else  goto _L1
_L1:
        JVM INSTR pop ;
        CGLIB$BIND_CALLBACKS( this);
        CGLIB$CALLBACK_0;
_L2:
        JVM INSTR dup ;
        JVM INSTR ifnull 37;
            goto _L3 _L4
_L3:
         break MISSING_BLOCK_LABEL_21;
_L4:
         break MISSING_BLOCK_LABEL_37;
         this;
        CGLIB$query$2$Method;
        CGLIB$emptyArgs;
        CGLIB$query$2$Proxy;
        intercept();
         return;
         super.query();
         return;
    }

     final  void CGLIB$update$3()
    {
         super.update();
    }

     public  final  void update()
    {
        CGLIB$CALLBACK_0;
         if(CGLIB$CALLBACK_0 !=  nullgoto _L2;  else  goto _L1
_L1:
        JVM INSTR pop ;
        CGLIB$BIND_CALLBACKS( this);
        CGLIB$CALLBACK_0;
_L2:
        JVM INSTR dup ;
        JVM INSTR ifnull 37;
            goto _L3 _L4
_L3:
         break MISSING_BLOCK_LABEL_21;
_L4:
         break MISSING_BLOCK_LABEL_37;
         this;
        CGLIB$update$3$Method;
        CGLIB$emptyArgs;
        CGLIB$update$3$Proxy;
        intercept();
         return;
         super.update();
         return;
    }

     final  void CGLIB$finalize$4()
         throws Throwable
    {
         super.finalize();
    }

     protected  final  void finalize()
         throws Throwable
    {
        CGLIB$CALLBACK_0;
         if(CGLIB$CALLBACK_0 !=  nullgoto _L2;  else  goto _L1
_L1:
        JVM INSTR pop ;
        CGLIB$BIND_CALLBACKS( this);
        CGLIB$CALLBACK_0;
_L2:
        JVM INSTR dup ;
        JVM INSTR ifnull 37;
            goto _L3 _L4
_L3:
         break MISSING_BLOCK_LABEL_21;
_L4:
         break MISSING_BLOCK_LABEL_37;
         this;
        CGLIB$finalize$4$Method;
        CGLIB$emptyArgs;
        CGLIB$finalize$4$Proxy;
        intercept();
         return;
         super.finalize();
         return;
    }

     final  int CGLIB$hashCode$5()
    {
         return  super.hashCode();
    }

     public  final  int hashCode()
    {
        CGLIB$CALLBACK_0;
         if(CGLIB$CALLBACK_0 !=  nullgoto _L2;  else  goto _L1
_L1:
        JVM INSTR pop ;
        CGLIB$BIND_CALLBACKS( this);
        CGLIB$CALLBACK_0;
_L2:
        JVM INSTR dup ;
        JVM INSTR ifnull 52;
            goto _L3 _L4
_L3:
         this;
        CGLIB$hashCode$5$Method;
        CGLIB$emptyArgs;
        CGLIB$hashCode$5$Proxy;
        intercept();
        JVM INSTR dup ;
        JVM INSTR ifnonnull 45;
            goto _L5 _L6
_L5:
        JVM INSTR pop ;
        0;
           goto _L7
_L6:
        (Number);
        intValue();
_L7:
         return;
_L4:
         return  super.hashCode();
    }

     final Object CGLIB$clone$6()
         throws CloneNotSupportedException
    {
         return  super.clone();
    }

     protected  final Object clone()
         throws CloneNotSupportedException
    {
        CGLIB$CALLBACK_0;
         if(CGLIB$CALLBACK_0 !=  nullgoto _L2;  else  goto _L1
_L1:
        JVM INSTR pop ;
        CGLIB$BIND_CALLBACKS( this);
        CGLIB$CALLBACK_0;
_L2:
        JVM INSTR dup ;
        JVM INSTR ifnull 37;
            goto _L3 _L4
_L3:
         this;
        CGLIB$clone$6$Method;
        CGLIB$emptyArgs;
        CGLIB$clone$6$Proxy;
        intercept();
         return;
_L4:
         return  super.clone();
    }

     final  boolean CGLIB$equals$7(Object obj)
    {
         return  super.equals(obj);
    }

     public  final  boolean equals(Object obj)
    {
        CGLIB$CALLBACK_0;
         if(CGLIB$CALLBACK_0 !=  nullgoto _L2;  else  goto _L1
_L1:
        JVM INSTR pop ;
        CGLIB$BIND_CALLBACKS( this);
        CGLIB$CALLBACK_0;
_L2:
        JVM INSTR dup ;
        JVM INSTR ifnull 57;
            goto _L3 _L4
_L3:
         this;
        CGLIB$equals$7$Method;
         new Object[] {
            obj
        };
        CGLIB$equals$7$Proxy;
        intercept();
        JVM INSTR dup ;
        JVM INSTR ifnonnull 50;
            goto _L5 _L6
_L5:
        JVM INSTR pop ;
         false;
           goto _L7
_L6:
        (Boolean);
        booleanValue();
_L7:
         return;
_L4:
         return  super.equals(obj);
    }

     final String CGLIB$toString$8()
    {
         return  super.toString();
    }

     public  final String toString()
    {
        CGLIB$CALLBACK_0;
         if(CGLIB$CALLBACK_0 !=  nullgoto _L2;  else  goto _L1
_L1:
        JVM INSTR pop ;
        CGLIB$BIND_CALLBACKS( this);
        CGLIB$CALLBACK_0;
_L2:
        JVM INSTR dup ;
        JVM INSTR ifnull 40;
            goto _L3 _L4
_L3:
         this;
        CGLIB$toString$8$Method;
        CGLIB$emptyArgs;
        CGLIB$toString$8$Proxy;
        intercept();
        (String);
         return;
_L4:
         return  super.toString();
    }

     public  static MethodProxy CGLIB$findMethodProxy(Signature signature)
    {
        String s = signature.toString();
        s;
        s.hashCode();
        JVM INSTR lookupswitch 9:  default 200
     //                    -1949253108: 92
    
//                    -1574182249: 104
    
//                    -1166709331: 116
    
//                    -508378822: 128
    
//                    -358764054: 140
    
//                    598313209: 152
    
//                    1826985398: 164
    
//                    1913648695: 176
    
//                    1984935277: 188;
            goto _L1 _L2 _L3 _L4 _L5 _L6 _L7 _L8 _L9 _L10
_L2:
        "update()V";
        equals();
        JVM INSTR ifeq 201;
            goto _L11 _L12
_L12:
         break MISSING_BLOCK_LABEL_201;
_L11:
         return CGLIB$update$3$Proxy;
_L3:
        "finalize()V";
        equals();
        JVM INSTR ifeq 201;
            goto _L13 _L14
_L14:
         break MISSING_BLOCK_LABEL_201;
_L13:
         return CGLIB$finalize$4$Proxy;
_L4:
        "query()V";
        equals();
        JVM INSTR ifeq 201;
            goto _L15 _L16
_L16:
         break MISSING_BLOCK_LABEL_201;
_L15:
         return CGLIB$query$2$Proxy;
_L5:
        "clone()Ljava/lang/Object;";
        equals();
        JVM INSTR ifeq 201;
            goto _L17 _L18
_L18:
         break MISSING_BLOCK_LABEL_201;
_L17:
         return CGLIB$clone$6$Proxy;
_L6:
        "delete()V";
        equals();
        JVM INSTR ifeq 201;
            goto _L19 _L20
_L20:
         break MISSING_BLOCK_LABEL_201;
_L19:
         return CGLIB$delete$0$Proxy;
_L7:
        "create()V";
        equals();
        JVM INSTR ifeq 201;
            goto _L21 _L22
_L22:
         break MISSING_BLOCK_LABEL_201;
_L21:
         return CGLIB$create$1$Proxy;
_L8:
        "equals(Ljava/lang/Object;)Z";
        equals();
        JVM INSTR ifeq 201;
            goto _L23 _L24
_L24:
         break MISSING_BLOCK_LABEL_201;
_L23:
         return CGLIB$equals$7$Proxy;
_L9:
        "toString()Ljava/lang/String;";
        equals();
        JVM INSTR ifeq 201;
            goto _L25 _L26
_L26:
         break MISSING_BLOCK_LABEL_201;
_L25:
         return CGLIB$toString$8$Proxy;
_L10:
        "hashCode()I";
        equals();
        JVM INSTR ifeq 201;
            goto _L27 _L28
_L28:
         break MISSING_BLOCK_LABEL_201;
_L27:
         return CGLIB$hashCode$5$Proxy;
_L1:
        JVM INSTR pop ;
         return  null;
    }

     public  static  void CGLIB$SET_THREAD_CALLBACKS(Callback acallback[])
    {
        CGLIB$THREAD_CALLBACKS.set(acallback);
    }

     public  static  void CGLIB$SET_STATIC_CALLBACKS(Callback acallback[])
    {
        CGLIB$STATIC_CALLBACKS = acallback;
    }

     private  static  final  void CGLIB$BIND_CALLBACKS(Object obj)
    {
        CGLIB.STATIC_CALLBACKS static_callbacks = (CGLIB.STATIC_CALLBACKS)obj;
         if(static_callbacks.CGLIB$BOUND)  goto _L2;  else  goto _L1
_L1:
        Object obj1;
        static_callbacks.CGLIB$BOUND =  true;
        obj1 = CGLIB$THREAD_CALLBACKS.get();
        obj1;
         if(obj1 !=  nullgoto _L4;  else  goto _L3
_L3:
        JVM INSTR pop ;
        CGLIB$STATIC_CALLBACKS;
         if(CGLIB$STATIC_CALLBACKS !=  nullgoto _L4;  else  goto _L5
_L5:
        JVM INSTR pop ;
           goto _L2
_L4:
        (Callback[]);
        static_callbacks;
        JVM INSTR swap ;
        0;
        JVM INSTR aaload ;
        (MethodInterceptor);
        CGLIB$CALLBACK_0;
_L2:
    }

     public Object newInstance(Callback acallback[])
    {
        CGLIB$SET_THREAD_CALLBACKS(acallback);
        CGLIB$SET_THREAD_CALLBACKS( null);
         return  new <init>();
    }

     public Object newInstance(Callback callback)
    {
        CGLIB$SET_THREAD_CALLBACKS( new Callback[] {
            callback
        });
        CGLIB$SET_THREAD_CALLBACKS( null);
         return  new <init>();
    }

     public Object newInstance(Class aclass[], Object aobj[], Callback acallback[])
    {
        CGLIB$SET_THREAD_CALLBACKS(acallback);
        JVM INSTR  new #2   <Class InfoManager$$EnhancerByCGLIB$$de624598>;
        JVM INSTR dup ;
        aclass;
        aclass.length;
        JVM INSTR tableswitch 0 0:  default 35
     //                    0 28;
            goto _L1 _L2
_L2:
        JVM INSTR pop ;
        <init>();
           goto _L3
_L1:
        JVM INSTR pop ;
         throw  new IllegalArgumentException("Constructor not found");
_L3:
        CGLIB$SET_THREAD_CALLBACKS( null);
         return;
    }

     public Callback getCallback( int i)
    {
        CGLIB$BIND_CALLBACKS( this);
         this;
        i;
        JVM INSTR tableswitch 0 0:  default 30
     //                    0 24;
            goto _L1 _L2
_L2:
        CGLIB$CALLBACK_0;
           goto _L3
_L1:
        JVM INSTR pop ;
         null;
_L3:
         return;
    }

     public  void setCallback( int i, Callback callback)
    {
         this;
        callback;
        i;
        JVM INSTR tableswitch 0 0:  default 29
     //                    0 20;
            goto _L1 _L2
_L2:
        (MethodInterceptor);
        CGLIB$CALLBACK_0;
           goto _L3
_L1:
        JVM INSTR pop2 ;
_L3:
    }

     public Callback[] getCallbacks()
    {
        CGLIB$BIND_CALLBACKS( this);
         this;
         return ( new Callback[] {
            CGLIB$CALLBACK_0
        });
    }

     public  void setCallbacks(Callback acallback[])
    {
         this;
        acallback;
        JVM INSTR dup2 ;
        0;
        JVM INSTR aaload ;
        (MethodInterceptor);
        CGLIB$CALLBACK_0;
    }

     private  boolean CGLIB$BOUND;
     private  static  final ThreadLocal CGLIB$THREAD_CALLBACKS;
     private  static  final Callback CGLIB$STATIC_CALLBACKS[];
     private MethodInterceptor CGLIB$CALLBACK_0;
     private  static  final Method CGLIB$delete$0$Method;
     private  static  final MethodProxy CGLIB$delete$0$Proxy;
     private  static  final Object CGLIB$emptyArgs[];
     private  static  final Method CGLIB$create$1$Method;
     private  static  final MethodProxy CGLIB$create$1$Proxy;
     private  static  final Method CGLIB$query$2$Method;
     private  static  final MethodProxy CGLIB$query$2$Proxy;
     private  static  final Method CGLIB$update$3$Method;
     private  static  final MethodProxy CGLIB$update$3$Proxy;
     private  static  final Method CGLIB$finalize$4$Method;
     private  static  final MethodProxy CGLIB$finalize$4$Proxy;
     private  static  final Method CGLIB$hashCode$5$Method;
     private  static  final MethodProxy CGLIB$hashCode$5$Proxy;
     private  static  final Method CGLIB$clone$6$Method;
     private  static  final MethodProxy CGLIB$clone$6$Proxy;
     private  static  final Method CGLIB$equals$7$Method;
     private  static  final MethodProxy CGLIB$equals$7$Proxy;
     private  static  final Method CGLIB$toString$8$Method;
     private  static  final MethodProxy CGLIB$toString$8$Proxy;

     static 
    {
        CGLIB$STATICHOOK1();
    }

     public ()
    {
        CGLIB$BIND_CALLBACKS( this);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
CGLIB是一个强大的,高性能的Java代码生成库,它是一个第三方类库,常被用来扩展Java类的功能。它通过在运行时生成字节码,动态地生成代理类来实现对目标对象的扩展,其实现原理与Java JDK自带的动态代理类似,但是CGLIB更加灵活。 CGLIB库的主要特点如下: 1. 高性能:CGLIB使用ASM字节码操作库来生成代理类,速度比使用Java反射要快很多。 2. 灵活性:CGLIB可以对类的任何方法进行代理,不像Java JDK的动态代理只能对接口的方法进行代理。 3. 支持继承代理:CGLIB可以代理普通的Java类,而不仅仅是实现接口的类。 4. 无需接口:CGLIB可以为没有实现任何接口的类创建代理对象。 CGLIB主要是通过在运行时生成目标对象的子类,以此来实现代理的目的。在运行时生成的子类重写了目标对象的方法,并且在重写的方法中添加了代理的逻辑,然后使用这个子类来代替目标对象。 CGLIB的使用需要依赖于cglib-nodep.jar库,这个库可以在CGLIB的官网上下载到。在使用CGLIB时,需要借助Enhancer类来生成代理对象,Enhancer类可以通过设置需要代理的目标类、实现的接口、回调方法等来生成代理对象。 下面是一个简单的使用CGLIB的示例代码: ```java import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor { private Object target; public Object getInstance(final Object target) { this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("before"); Object result = proxy.invokeSuper(obj, args); System.out.println("after"); return result; } } public class Main { public static void main(String[] args) { CglibProxy cglib = new CglibProxy(); UserDao userDao = (UserDao) cglib.getInstance(new UserDao()); userDao.save(); } } public class UserDao { public void save() { System.out.println("保存用户信息"); } } ``` 在这个示例代码中,CglibProxy类实现了MethodInterceptor接口,并且重写了intercept方法,在intercept方法中添加了代理的逻辑。在Main类中,首先实例化了CglibProxy类,然后通过cglib.getInstance方法生成了UserDao类的代理对象。最后,调用代理对象的save方法时,会先输出"before",然后

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值