cglib创建代理对象(1)

cglib创建代理对象

还是从一个的小demo开始

例子

  1. 被代理的类

    public class Bean{
        public String sayHello(String name) {
            return "Bean.sayHello";
        }
        private String  privateSayHello(String name){
            return "Bean.privateSayHello";
        }
        public String lipu1(){
            return "lipu";
        }
        private String privateLipu1(){
            return "privateLipu1";
        }
        public String jump(){
            return "jump";
        }
        private String privateJump(){
            return "privateJump";
        }
        public String hhhh(){
            return "hhhh";
        }
        private String privateHhhh(){
            return "hhhh";
        }
    
        public String dadada(){
            return "dadada";
        }
        private String privateDadada(){
            return "privateDadada";
        }
        public String lululu(){
            return "lululu";
        }
    
        private String privateLululu(){
            return "privateLululu";
        }}
    
  2. 主测试类

    public class SampleTest {
        public static void main(String[] args) {
             // 保存生成的class的路径,对应的代码在DebuggingClassWriter#DEBUG_LOCATION_PROPERTY字段,toByteArray方法
            System.getProperties().setProperty("cglib.debugLocation","C:\\Users\\Administrator\\Desktop\\temp");
            Enhancer enhancer = new Enhancer();
            final Bean bean = new Bean();
            enhancer.setSuperclass(Bean.class);
        // 下面的这些都是Callback,这些Callback是通过CallbackFilter来指定的。
            Dispatcher dispatcher = new Dispatcher() {
                @Override
                public Object loadObject() throws Exception {
                    System.out.println("SampleTest.loadObject");
                    return bean;
                }
            };
            MethodInterceptor methodInterceptor = new MethodInterceptor() {
                @Override
                public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                    System.out.println("SampleTest.intercept");
                    return "SampleTest.intercept";
                }
            };
            InvocationHandler invocationHandler = new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("SampleTest.invoke");
                    return "SampleTest.invoke";
                }
            };
            LazyLoader lazyLoader = new LazyLoader() {
                @Override
                public Object loadObject() throws Exception {
                    System.out.println("SampleTest.loadObject");
                   return bean;
                }
            };
            FixedValue fixedValue = new FixedValue() {
                @Override
                public Object loadObject() throws Exception {
                    System.out.println("SampleTest.loadObject");
                    return bean;
                }
            };
    
            ProxyRefDispatcher proxyRefDispatcher = new ProxyRefDispatcher() {
                @Override
                public Object loadObject(Object proxy) throws Exception {
                    return bean;
                }
            };
    
            Callback[] callbacks = {
                    dispatcher,
                    methodInterceptor,
                    invocationHandler,
                    lazyLoader,
                    fixedValue,
                    NoOp.INSTANCE,
                    proxyRefDispatcher
            };
    
    
           // 通过方法的名字来指定那个callback起作用
            CallbackFilter callbackFilter = new CallbackFilter() {
                @Override
                public int accept(Method method) {
                    System.out.println("SampleTest.accept:" + method.getName());
                 switch (method.getName()){
                     case "sayHello":
                         return 0;
                     case "lipu1":
                         return 1;
                     case "jump":
                         return 2;
                     case "hhhh":
                         return 3;
                     case "dadada":
                         return 4;
                     case "lululu":  // 如果是 NoOp.INSTANCE表示不需要代理,在生成的代理类里面没有操作,也就是代理类不会重写父类的方法
                         return 5;
                     case "sasasasa":
                         return 6;
                 }
                 return 0;
                }
            };
        
            enhancer.setCallbacks(callbacks);
            enhancer.setCallbackFilter(callbackFilter);
    
    
            Bean o = (Bean) enhancer.create();
            String test = o.sayHello("test");
            System.out.println(test);
        }
    }
    

概念解释

这里只是将正常使用的时候的两种常见的类型做解释,其余和Cglib有比较重要的概念在之后说

Callback

先看类图

在这里插入图片描述

关于各个的实现类的功能,已经在各个类的注释上说清楚了。可能有的意思还是不太懂,在本文的最后一节里面,贴出了生成的代理类,对比代理类,看看不同的Callback的子类的作用,就很清晰了。

子类解释
  1. MethodInterceptor:回调,可以通过MethodProxy调用父类,或者同一个类型的Bean的同名方法
  2. NoOp:什么都不做
  3. LazyLoader:懒加载,但是加载过之后,就不加载了。
  4. Dispatcher:做分派,每次都会调用。通过它返回的Bean来做同名方法的调用
  5. InvocationHandler:这就和JDK的一样,和MethodInterceptor不一样的是,它没有MethodProxy
  6. FixedValue:固定值。

CallbackFilter

在生成代理类的时候,代理类会重写父类的方法,在重写父类方法的时候,会通过它来判断要用哪个Callback。

accept方法返回的是Callback数组中的下标。在构建代理类的时候,就会使用Callback数组对应下标中的Callback。

public interface CallbackFilter {

    int accept(Method method);

    boolean equals(Object o);
}

在生成代理类的时候,代理类会重写父类的方法,在重写父类方法的时候,会通过它来判断要用哪个Callback。对应于(Enhancer#emitMethods,在这个方法里面有int index = filter.accept(actualMethod);代码)

如果传递的Callback多于一个,并且没有指定CallbackFilter的话,就会报错,如果CallBack就一个,它会给一个默认的CallbackFilter,总是返回0。(Enhancer#preValidate做判断,并且给默认值。)

这是和JDK-Proxy不同的一点,在JDK-Proxy是不能支持多个InvocationHandler,但是Cglib是可以的

这篇文章不具体的分析CGLIB创建代理对象的操作。旨在说清楚Callback子接口的作用,还有CallBackFilter。还有生成的代理类长什么样?

代理类

代理类的创建和生成是在内存里面的,不过可以通过配置,让生成的类保存起来,便于观察。通过下面的代码开启
System.getProperties().setProperty("cglib.debugLocation","C:\\Users\\Administrator\\Desktop\\temp");

在运行上面的例子之后,就会在指定的文件夹下面生成几个class文件

在这里插入图片描述

将生成的文件直接拖入Idea,idea会反编译。便于我们观察

代码比较多,详细的解释写在注释里面,这里会对这个类来做一些简单的说明:

  1. 在代理类里面保留callback子接口的引用关系,在不同的方法里面用不同的callback。

  2. private方法是不能被代理对象重写的, 可以看到上面例子里面private开头的方法,都没有被重写。

  3. 如果给一个方法指定的callback类型是NoOp.INSTANCE,那这个方法可能是不会被代理类重写的(可以看到,上面例子中lululu方法并没有被重写),这里说可能的意思是NoOp也有NoOpGenerator,具体的代码逻辑在NoOpGenerator#generate。它要求满足下面才可以重写。

在这里插入图片描述

看这个代码逻辑,有两个问题,

  • Method有区分,OriginalMethod和Method有什么区别?
  • OriginalMethod为public,代理的方法为Public是什么样的场景?

具体在后面分析

  1. 所有通过Enhancer生成的代理类都实现了Factory接口

在这里插入图片描述

通过这个接口可以很快的创建代理类(很快的意思是,如果要创建一个和当前代理类在同样的方法用同样的callback类型,但是行为不一样,创建起来比较快,因为直接new 对象就好了,但是如果要通过Enhancer来做的,就比较慢了,快就快在这里了,如果用Enhancer来做,起码要在内存里面编织字节码,这一点就比较慢了)只要指定Callback就可以创建代理类,可以动态的修改Callback(也就是可以动态的修改行为),还可以获取Callback。

  1. equals,toString,hashCode,clone也会走callbackFilter的逻辑,但是这里要注意了,对于protected修饰的方法,不同的CallbackGenerator有不同的要求

    DispatcherGenerator:不支持重写(DispatcherGenerator#generate方法里面有if (!TypeUtils.isProtected(method.getModifiers()))判断)

    FixedValueGenerator:支持(FixedValueGenerator#generate方法里面没有类似上面的判断)

    InvocationHandlerGenerator:支持(InvocationHandlerGenerator#generate,没有类似上面的判断)

    LazyLoaderGenerator:不支持(LazyLoaderGenerator#generate,TypeUtils.isProtected(method.getModifiers())

    MethodInterceptorGenerator:支持(MethodInterceptorGenerator#generate)

    NoOpGenerator:不支持(NoOpGenerator#generate)

  2. MethodInterceptor 应用的方法比较特殊,和普通的不一样

    • 属性中多了一个MethodProxy的引用,并且还多了一个以CGLIB开头,中间是方法名字,后面是Proxy结尾的方法,在这个方法里面直接调用了父类的方法。

在这里插入图片描述

  • 多的这个方法有什么用?创建的MethodProxy有什么用?

    创建的MethodProxy是要通过MethodInterceptor传递的,我们在日常用的时候可以直接调用MethodProxy的invokeSuper,来调用父类(被代理的类)的方法。

    这个操作就会调用到多出来的这个方法(对比到上图中就是GLIB$lipu1$2方法)。首先调用super肯定不能直接调用到lipu1方法。如果调用到,就陷入到循环里面了。这就像在JDK-proxy的时候,在InvocationHandler里面通过第一个参数(proxy)来做调用会导致栈溢出,因为陷入到无限套娃里面了。

在这里插入图片描述

所以,就得单独搞一个方法,不要走MethodInterceptor的拦截操作。就不会有栈溢出的问题了。

此外,MethodProxy还有别的作用,可以通过MethodProxy来调用指定对象的目标方法(对应的就是invoke(Object,Object[]))方法。在利用MethodProxy做调用的时候,这个过程还会生成两个代理类。通过这两代理类做调用。

在这里插入图片描述

  1. MethodProxy解释

    方法和属性都在上面展示了,这里说几个问题

    • 代理对象中的MethodProxy赋值操作

      具体的代码在MethodInterceptorGenerator#generate里面。会在代理类里面静态的引用,在静态代码块里面会通过MethodProxy#create(Class c1, Class c2, String desc, String name1, String name2)来创建。方法的参数从左到右为,被代理类对象,代理类对象,方法签名(方法参数,返回值等等),属于被代理对象方法签名一样的方法名称,属于代理对象方法签名一样的方法名称。

      现在看起来有点模糊,在之后的文章里面会详细的解释清楚的。

    • 在通过MethodProxy来调用方法的时候,也会创建动态的创建两个类。

      具体的代码在MethodProxy#helper方里面。在每次调用MethodProxy的invoke或者invokeSuper的时候,都会调用init方法,init方法里面会调用到helper方法。在这里面会创建一个类。

         private static FastClass helper(CreateInfo ci, Class type) {
              FastClass.Generator g = new FastClass.Generator();
              g.setType(type);
              g.setClassLoader(ci.c2.getClassLoader());
              g.setNamingPolicy(ci.namingPolicy);
              g.setStrategy(ci.strategy);
              g.setAttemptLoad(ci.attemptLoad);
              return g.create();
          }
      

      这个Generator是FastClass的内部类,也是继承了AbstractClassGenerator,可以生成类。

  2. 代理类中方法名字生成的逻辑在哪里,class文件的命名是什么样的规则?

  • NamingPolicy接口,用来生成class文件的名字,DefaultNamingPolicy是它的默认的实现类。
  • 方法名字生成逻辑和代码生成逻辑

主要在CallbackGenerator的实现类里面,通过不同的实现类,来生成不同类型的代码。在这里面会通过Context来获取字段的信息。

在这里插入图片描述

  • 静态方法名字生成逻辑

在这里插入图片描述

生成的代理类

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package net.sf.cglib.samples.simple;

import java.lang.reflect.Method;
import net.sf.cglib.core.ReflectUtils;
import net.sf.cglib.core.Signature;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Dispatcher;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.FixedValue;
import net.sf.cglib.proxy.InvocationHandler;
import net.sf.cglib.proxy.LazyLoader;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.proxy.NoOp;
import net.sf.cglib.proxy.ProxyRefDispatcher;
import net.sf.cglib.proxy.UndeclaredThrowableException;
// 生成的代理类会继承要代理的类,并且实现Factory接口
public class Bean$$EnhancerByCGLIB$$d79f67a6 extends Bean implements Factory {
    // 标志位,表示是否初始化过,默认值是false
    private boolean CGLIB$BOUND;
    public static Object CGLIB$FACTORY_DATA;
    // 利用ThreadLocal来存储Callback[]
    private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
    // Callback[] 
    private static final Callback[] CGLIB$STATIC_CALLBACKS;
    
    // 下面的这几个属性都是在创建代理对象的时候,通过Enhancer传递进来的Callback
    // 传递进来的dispatch
    private Dispatcher CGLIB$CALLBACK_0;
     //传递进来的MethodInterceptor
    private MethodInterceptor CGLIB$CALLBACK_1;
    // InvocationHandler
    private InvocationHandler CGLIB$CALLBACK_2;
    private LazyLoader CGLIB$CALLBACK_3;
    private FixedValue CGLIB$CALLBACK_4;
    private NoOp CGLIB$CALLBACK_5;
    private ProxyRefDispatcher CGLIB$CALLBACK_6;
    
    // LazyLoader的引用的返回值的引用
    private static Object CGLIB$CALLBACK_FILTER;
    //liupu1方法的引用,而且这个引用是属于Bean对象的
    private static final Method CGLIB$lipu1$2$Method;
    //MethodProxy对象,可以看下面的CGLIB$STATICHOOK1方法,va1是Bean的class对象,var0是当前代理对象的class对象。
    // ()Ljava/lang/String;是方法的签名,lipu1和CGLIB$lipu1$2是不同的类对象的不同方法名字。
    private static final MethodProxy CGLIB$lipu1$2$Proxy;
    // 空参数对象,这就一个默认值
    private static final Object[] CGLIB$emptyArgs;
     // bean对象的jump方法引用
    private static final Method CGLIB$jump$5;
    // lazyLoader加载引用关系
    private Object CGLIB$LAZY_LOADER_3;
     
    static void CGLIB$STATICHOOK1() {
        // 赋值
        CGLIB$THREAD_CALLBACKS = new ThreadLocal();
        CGLIB$emptyArgs = new Object[0];
        Class var0 = Class.forName("net.sf.cglib.samples.simple.Bean$$EnhancerByCGLIB$$d79f67a6");
        Class var1;
        CGLIB$lipu1$2$Method = ReflectUtils.findMethods(new String[]{"lipu1", "()Ljava/lang/String;"}, (var1 = Class.forName("net.sf.cglib.samples.simple.Bean")).getDeclaredMethods())[0];
        CGLIB$lipu1$2$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "lipu1", "CGLIB$lipu1$2");
        CGLIB$jump$5 = Class.forName("net.sf.cglib.samples.simple.Bean").getDeclaredMethod("jump");
    }
    //sayHello用的callback是Dispatcher, 
    public final String sayHello(String var1) {
        // 每个变量都是关联好的,在什么方法用什么callback都是确定好的,
        Dispatcher var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return ((Bean)var10000.loadObject()).sayHello(var1);
    }
    // 
    public final boolean equals(Object var1) {
        Dispatcher var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return var10000.loadObject().equals(var1);
    }
    
    public final String toString() {
        Dispatcher var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return var10000.loadObject().toString();
    }
  
    public final int hashCode() {
        Dispatcher var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }

        return var10000.loadObject().hashCode();
    }
   // 要注意这个方法,这是 MethodProxy CGLIB$lipu1$2$Proxy属性里面的,在通过MethodProxy.invokeSuper的时候会调用到这个方法
    final String CGLIB$lipu1$2() {
        return super.lipu1();
    }
   // lipu1用的是methodInterceptor,在调用的时候会将CGLIB$lipu1$2$Proxy传递过去,并且,因为这个方法没有入参, 	
    public final String lipu1() {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_1;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_1;
        }

        return var10000 != null ? (String)var10000.intercept(this, CGLIB$lipu1$2$Method, CGLIB$emptyArgs, CGLIB$lipu1$2$Proxy) : super.lipu1();
    }
   //静态方法,获取MethodProxy,通过方法的签名,这个签名对象有俩个字段,名字描述
    public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
        String var10000 = var0.toString();
        switch(var10000.hashCode()) {
        case -286557062:
            if (var10000.equals("lipu1()Ljava/lang/String;")) {
                return CGLIB$lipu1$2$Proxy;
            }
        }

        return null;
    }
   // 用的是invocationHandler
    public final String jump() {
        try {
            InvocationHandler var10000 = this.CGLIB$CALLBACK_2;
            // 这是做初始化操作的
            if (var10000 == null) {
                CGLIB$BIND_CALLBACKS(this);
                var10000 = this.CGLIB$CALLBACK_2;
            }

            return (String)var10000.invoke(this, CGLIB$jump$5, new Object[0]);
        } catch (Error | RuntimeException var1) {
            throw var1;
        } catch (Throwable var2) {
            throw new UndeclaredThrowableException(var2);
        }
    }
    // 用的是lazyLoader
    public final String hhhh() {
        // 它调用的是CGLIB$LOAD_PRIVATE_3方法,然后再调用hhh方法
        //CGLIB$LOAD_PRIVATE_3在下面方法声明,在它里面会先看是否调用过,没有调用过,才会调用loadObject,。通过loadObject返回的对象来
        // 调用hhh方法
        return ((Bean)this.CGLIB$LOAD_PRIVATE_3()).hhhh();
    }

    private final synchronized Object CGLIB$LOAD_PRIVATE_3() {
        Object var10000 = this.CGLIB$LAZY_LOADER_3;
        if (var10000 == null) {
            LazyLoader var10001 = this.CGLIB$CALLBACK_3;
            if (var10001 == null) {
                CGLIB$BIND_CALLBACKS(this);
                var10001 = this.CGLIB$CALLBACK_3;
            }

            var10000 = this.CGLIB$LAZY_LOADER_3 = var10001.loadObject();
        }

        return var10000;
    }
 // 用的是fixedValue,这个比较重要,直接返回loadObject方法返回的值。
    public final String dadada() {
        FixedValue var10000 = this.CGLIB$CALLBACK_4;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_4;
        }

        return (String)var10000.loadObject();
    }
// proxyRefDispatcher 在调用的时候,会将代理对象传递过去,还是和之前一样,做调用
    public final String sasasasa() {
        ProxyRefDispatcher var10000 = this.CGLIB$CALLBACK_6;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_6;
        }

        return ((Bean)var10000.loadObject(this)).sasasasa();
    }
    // 构造方法
    public Bean$$EnhancerByCGLIB$$d79f67a6() {
        CGLIB$BIND_CALLBACKS(this);
    }
    //给ThreadLoacal设置callBack[]
    public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {
        CGLIB$THREAD_CALLBACKS.set(var0);
    }
   // 改变callback[],注意,看这个名字有一个static,上面的名字里面有一个Thread
    public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] var0) {
        CGLIB$STATIC_CALLBACKS = var0;
    }
   // 私有静态方法,用这个方法来给CGLIB$CALLBACK_6这些赋值,首先会从ThreadLocal中获取值,再回从静态的callback[]里面获取值
    private static final void CGLIB$BIND_CALLBACKS(Object var0) {
        Bean$$EnhancerByCGLIB$$d79f67a6 var1 = (Bean$$EnhancerByCGLIB$$d79f67a6)var0;
        if (!var1.CGLIB$BOUND) {
            var1.CGLIB$BOUND = true;
            Object var10000 = CGLIB$THREAD_CALLBACKS.get();
            if (var10000 == null) {
                var10000 = CGLIB$STATIC_CALLBACKS;
                if (var10000 == null) {
                    return;
                }
            }
              // 赋值
            Callback[] var10001 = (Callback[])var10000;
            var1.CGLIB$CALLBACK_6 = (ProxyRefDispatcher)((Callback[])var10000)[6];
            var1.CGLIB$CALLBACK_5 = (NoOp)var10001[5];
            var1.CGLIB$CALLBACK_4 = (FixedValue)var10001[4];
            var1.CGLIB$CALLBACK_3 = (LazyLoader)var10001[3];
            var1.CGLIB$CALLBACK_2 = (InvocationHandler)var10001[2];
            var1.CGLIB$CALLBACK_1 = (MethodInterceptor)var10001[1];
            var1.CGLIB$CALLBACK_0 = (Dispatcher)var10001[0];
        }

    }
   // 这个方法是Factory接口的方法,所有通过Enhancer生成的代理类都实现了这个接口,利用这个接口就可以快速的创建实例,
    // 改变callback,获取callback
    public Object newInstance(Callback[] var1) {
        CGLIB$SET_THREAD_CALLBACKS(var1);
        Bean$$EnhancerByCGLIB$$d79f67a6 var10000 = new Bean$$EnhancerByCGLIB$$d79f67a6();
        CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
        return var10000;
    }

    public Object newInstance(Callback var1) {
        throw new IllegalStateException("More than one callback object required");
    }

    public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
        CGLIB$SET_THREAD_CALLBACKS(var3);
        Bean$$EnhancerByCGLIB$$d79f67a6 var10000 = new Bean$$EnhancerByCGLIB$$d79f67a6;
        switch(var1.length) {
        case 0:
            var10000.<init>();
            CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
            return var10000;
        default:
            throw new IllegalArgumentException("Constructor not found");
        }
    }

    public Callback getCallback(int var1) {
        CGLIB$BIND_CALLBACKS(this);
        Object var10000;
        switch(var1) {
        case 0:
            var10000 = this.CGLIB$CALLBACK_0;
            break;
        case 1:
            var10000 = this.CGLIB$CALLBACK_1;
            break;
        case 2:
            var10000 = this.CGLIB$CALLBACK_2;
            break;
        case 3:
            var10000 = this.CGLIB$CALLBACK_3;
            break;
        case 4:
            var10000 = this.CGLIB$CALLBACK_4;
            break;
        case 5:
            var10000 = this.CGLIB$CALLBACK_5;
            break;
        case 6:
            var10000 = this.CGLIB$CALLBACK_6;
            break;
        default:
            var10000 = null;
        }

        return (Callback)var10000;
    }

    public void setCallback(int var1, Callback var2) {
        switch(var1) {
        case 0:
            this.CGLIB$CALLBACK_0 = (Dispatcher)var2;
            break;
        case 1:
            this.CGLIB$CALLBACK_1 = (MethodInterceptor)var2;
            break;
        case 2:
            this.CGLIB$CALLBACK_2 = (InvocationHandler)var2;
            break;
        case 3:
            this.CGLIB$CALLBACK_3 = (LazyLoader)var2;
            break;
        case 4:
            this.CGLIB$CALLBACK_4 = (FixedValue)var2;
            break;
        case 5:
            this.CGLIB$CALLBACK_5 = (NoOp)var2;
            break;
        case 6:
            this.CGLIB$CALLBACK_6 = (ProxyRefDispatcher)var2;
        }

    }

    public Callback[] getCallbacks() {
        CGLIB$BIND_CALLBACKS(this);
        return new Callback[]{this.CGLIB$CALLBACK_0, this.CGLIB$CALLBACK_1, this.CGLIB$CALLBACK_2, this.CGLIB$CALLBACK_3, this.CGLIB$CALLBACK_4, this.CGLIB$CALLBACK_5, this.CGLIB$CALLBACK_6};
    }

    public void setCallbacks(Callback[] var1) {
        this.CGLIB$CALLBACK_0 = (Dispatcher)var1[0];
        this.CGLIB$CALLBACK_1 = (MethodInterceptor)var1[1];
        this.CGLIB$CALLBACK_2 = (InvocationHandler)var1[2];
        this.CGLIB$CALLBACK_3 = (LazyLoader)var1[3];
        this.CGLIB$CALLBACK_4 = (FixedValue)var1[4];
        this.CGLIB$CALLBACK_5 = (NoOp)var1[5];
        this.CGLIB$CALLBACK_6 = (ProxyRefDispatcher)var1[6];
    }

    static {
        CGLIB$STATICHOOK1();
    }
}

到此,结束了。

关于博客这件事,我是把它当做我的笔记,里面有很多的内容反映了我思考的过程,因为思维有限,不免有些内容有出入,如果有问题,欢迎指出。一同探讨。谢谢

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值