动态代理-Cglib实现原理

2020-08-21  本文已影响0人  立志java

动态代理-Cglib实现原理

Cglib提供了一种运行时动态增强类的功能。基于ASM在运行时动态创建class,暴露Callback接口用于对类和方法进行增强。通过Cglib不仅能够实现同JDK Proxy一样的基于接口和反射调用的增强类,同时也可以基于实现类对类进行增强,并且可以避免使用反射调用,而且使用了FastClass模式,运行效率要高于使用反射

知识导读

使用

创建一个非final的类,用于被增强

public class MacBookSeller {

    private String name;

    public MacBookSeller(String name) {
        this.name = name;
    }
    public MacBookSeller() {
        this.name = "未知";
    }
    public void sellComputor(String brand) {
        System.out.println("sell the MacBook computor");
    }
    public String repairComputor(String brand) {
        System.out.println("repair the MacBook computor:" + name);
        return name;
    }
}

来看个使用cglib对MacBookSeller类进行增强的例子

public static void main(String[] args) {
    //生成cglib生成的类
    System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, JdkProxy.class.getResource("/").getPath());
    //创建一个加强器 Enhancer对象
    Enhancer enhancer = new Enhancer();
    //设置要创建动态代理的类,即父类
    enhancer.setSuperclass(MacBookSeller.class);
    MacBookSeller macBookSeller = new MacBookSeller("苹果专卖店");
    // 设置回调,这里相当于是对于目标类上所有方法的调用,都会调用CallBack,而Callback则需要实行intercept()方法进行拦截
    enhancer.setCallback(new MethodInterceptor() {
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            if (method.getName().equalsIgnoreCase("repairComputor")) {
                System.out.println("开始代理");
                System.out.println(String.format("method name:%s,args:%s", method.getName(), JSON.toJSONString(args)));
                //增强类继承的目标类,调用父类的原方法
                Object o = proxy.invokeSuper(obj, args);//通过增强类调用目标类方法,注意obj是增强类对象
                Object o1 = proxy.invoke(macBookSeller, args);//直接通过父类对象调用
                System.out.println("通过增强类对象调用父类方法结果:" + o);//输出的name是增强类的name
                System.out.println("通过目标类对象直接调用目标方法结果:" + o1);//输出的name是父类的name
                System.out.println("结束代理");
                return o;//调用增强类对象方法的返回值
            }
            return null;
        }
    });
    //创建代理类对象 指定构造器
    MacBookSeller proxy = MacBookSeller.class.cast(enhancer.create(new Class[]{String.class}, new String[]{"proxy"}));
    System.out.println("proxy对象:" + proxy.getClass().getName());//cn.zlz.proxy.cglib.MacBookSeller$$EnhancerByCGLIB$$9c2b1abb
    String result = proxy.repairComputor("mac book pro");
    System.out.println("调用增强类对象的repairComputor方法返回结果:" + result);
}

Enhancer类中也提供了静态方法可以直接创建增强类对象

public static Object create(Class superclass, Class[] interfaces, CallbackFilter filter, Callback[] callbacks) {
    Enhancer e = new Enhancer();
    e.setSuperclass(superclass);
    e.setInterfaces(interfaces);
    e.setCallbackFilter(filter);
    e.setCallbacks(callbacks);
    return e.create();
}

当要增强类中的不同方法需要不同的增强处理,可以指定多个Callback实现,同时使用CallbackFilter来给不同的方法分配不同的Callback来进行增强

public static void main(String[] args) {
    System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, JdkProxy.class.getResource("/").getPath());
    //创建一个加强器 Enhancer对象
    Enhancer enhancer = new Enhancer();
    //设置要创建动态代理的类,即父类
    enhancer.setSuperclass(MacBookSeller.class);
    MethodInterceptor methodInterceptor1 = new MethodInterceptor() {
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("开始代理1");
            //代理类是继承的被代理类,调用父类的原方法
            Object o = proxy.invokeSuper(obj, args);
            System.out.println(String.format("被代理方法返回值0:%s", o));
            System.out.println("结束代理1");
            return o;
        }
    };
    MethodInterceptor methodInterceptor2 = new MethodInterceptor() {
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("开始代理2");
            //代理类是继承的被代理类,调用父类的原方法
            Object o = proxy.invokeSuper(obj, args);
            System.out.println(String.format("被代理方法返回值0:%s", o));
            System.out.println("结束代理2");
            return o;
        }
    };

    // 设置回调,这里相当于是对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实行intercept()方法进行拦截
    Callback[] callbacks = {methodInterceptor1, methodInterceptor2, NoOp.INSTANCE};
    enhancer.setCallbacks(callbacks);
    //CallbackFilter对应Callbacks中的,用于指定方法使用哪个Callback
    CallbackFilter callbackFilter = new CallbackFilter() {
        @Override
        public int accept(Method method) {
            if (method.getName().equalsIgnoreCase("repairComputor")) {
                return 0;//使用数组中的一个 MethodInterceptor
            } else if (method.getName().equalsIgnoreCase("sellComputor")) {
                return 1;//使用Callback数组中的第二个  MethodInterceptor
            } else {
                return 2;//其他方法使用NoOp不进行任何增强
            }
        }
    };
    enhancer.setCallbackFilter(callbackFilter);
    MacBookSeller proxy = MacBookSeller.class.cast(Enhancer.create(MacBookSeller.class, null, callbackFilter, callbacks));
    proxy.repairComputor("mac book pro");
    proxy.sellComputor("mac book pro");
}

Cglib不仅可以基于实现类来进行增强,同时也可以实现JDK的代理,在Cglib中提供了一个InvocationHandler接口实现了Callback接口,通过设置一个InvocationHandler实现可以创建一个和JDK代理实现方式一样的增强类,调用是基于反射来实现的,来看下面例子

public static void main(String[] args) {
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, JdkProxy.class.getResource("/").getPath());
        //创建一个加强器 Enhancer对象
        Enhancer enhancer = new Enhancer();
        //设置要创建动态代理接口
        enhancer.setInterfaces(new Class[]{IComputorService.class});
        Callback invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
                System.out.println(proxy.getClass().getName());
                System.out.println("method:" + method.getName());
//                return method.invoke(proxy, args);
                boolean enhanced = Enhancer.isEnhanced(proxy.getClass());
                System.out.println("是否增强:"+enhanced);
                return null;
            }
        };
        enhancer.setCallbacks(new Callback[]{invocationHandler, NoOp.INSTANCE});
        enhancer.setCallbackFilter(new CallbackFilter() {
            @Override
            public int accept(Method method) {
                //invocationHandler只拦截repairComputor和sellComputor两个方法
                if(method.getName().equalsIgnoreCase("repairComputor") ||method.getName().equalsIgnoreCase("sellComputor")) {
                    return 0;
                }else {//使用NoOp不对其他方法进行增强
                    return 1;
                }
            }
        });
        //创建代理类对象
        IComputorService proxy = IComputorService.class.cast(enhancer.create());
        proxy.repairComputor("mac book pro");
    }

原理

cglib基于继承目标类创建子类进行增强的时候,会动态创建3个类,一个是通过Enhancer创建一个目标类的实现类,另外两个是通过MethodProxy创建的FastClass,分别对应增强前的目标类的FastClass和增强类的FastClass,FastClass用于基于索引访问对象的方法。首先来看动态生成的增强类

public class MacBookSeller$$EnhancerByCGLIB$$b857906a extends MacBookSeller implements Factory {
    private boolean CGLIB$BOUND;
    //用于存储和线程绑定 Callback
    private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
    //Callback 用于对方法进行增强
    private static final Callback[] CGLIB$STATIC_CALLBACKS;
    //因为在生成的时候传递了3个Callback,所有会有3个
    private MethodInterceptor CGLIB$CALLBACK_0;
    private MethodInterceptor CGLIB$CALLBACK_1;
    private NoOp CGLIB$CALLBACK_2;
    private static final Method CGLIB$repairComputor$0$Method;
    //对应 repairComputor 的MethodProxy
    private static final MethodProxy CGLIB$repairComputor$0$Proxy;
    private static final Object[] CGLIB$emptyArgs;
    private static final Method CGLIB$sellComputor$1$Method;
     //对应 sellComputor 的MethodProxy
    private static final MethodProxy CGLIB$sellComputor$1$Proxy;

    static void CGLIB$STATICHOOK1() {
        CGLIB$THREAD_CALLBACKS = new ThreadLocal();
        Class var0;
        ClassLoader var10000 = (var0 = Class.forName("cn.zlz.proxy.cglib.MacBookSeller$$EnhancerByCGLIB$$b857906a")).getClassLoader();
        CGLIB$emptyArgs = new Object[0];
        //创建MethodProxy
        CGLIB$repairComputor$0$Proxy = MethodProxy.create(var10000, (CGLIB$repairComputor$0$Method = Class.forName("cn.zlz.proxy.cglib.MacBookSeller").getDeclaredMethod("repairComputor", Class.forName("java.lang.String"))).getDeclaringClass(), var0, "(Ljava/lang/String;)Ljava/lang/String;", "repairComputor", "CGLIB$repairComputor$0");
       //创建MethodProxy
        CGLIB$sellComputor$1$Proxy = MethodProxy.create(var10000, (CGLIB$sellComputor$1$Method = Class.forName("cn.zlz.proxy.cglib.MacBookSeller").getDeclaredMethod("sellComputor", Class.forName("java.lang.String"))).getDeclaringClass(), var0, "(Ljava/lang/String;)V", "sellComputor", "CGLIB$sellComputor$1");
    }

    final String CGLIB$repairComputor$0(String var1) {
        //使用子类对象调用父类方法
        return super.repairComputor(var1);
    }

    //调用增强后的方法
    public final String repairComputor(String var1) {
        MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
        if (var10000 == null) {
            CGLIB$BIND_CALLBACKS(this);
            var10000 = this.CGLIB$CALLBACK_0;
        }
        //调用Callback的实现类实现
        return var10000 != null ? (String)var10000.intercept(this, CGLIB$repairComputor$0$Method, new Object[]{var1}, CGLIB$repairComputor$0$Proxy) : super.repairComputor(var1);
    }

    final void CGLIB$sellComputor$1(String var1) {
        super.sellComputor(var1);
    }

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

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

    public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
        String var10000 = var0.toString();
        switch(var10000.hashCode()) {
        case -819357441:
            if (var10000.equals("repairComputor(Ljava/lang/String;)Ljava/lang/String;")) {
                return CGLIB$repairComputor$0$Proxy;
            }
            break;
        case 667760668:
            if (var10000.equals("sellComputor(Ljava/lang/String;)V")) {
                return CGLIB$sellComputor$1$Proxy;
            }
        }
        return null;
    }

    public MacBookSeller$$EnhancerByCGLIB$$b857906a(String var1) {
        super(var1);
        CGLIB$BIND_CALLBACKS(this);
    }

    public MacBookSeller$$EnhancerByCGLIB$$b857906a() {
        CGLIB$BIND_CALLBACKS(this);
    }

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

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

    private static final void CGLIB$BIND_CALLBACKS(Object var0) {
        MacBookSeller$$EnhancerByCGLIB$$b857906a var1 = (MacBookSeller$$EnhancerByCGLIB$$b857906a)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_2 = (NoOp)((Callback[])var10000)[2];
            var1.CGLIB$CALLBACK_1 = (MethodInterceptor)var10001[1];
            var1.CGLIB$CALLBACK_0 = (MethodInterceptor)var10001[0];
        }

    }

    public Object newInstance(Callback[] var1) {
        CGLIB$SET_THREAD_CALLBACKS(var1);
        MacBookSeller$$EnhancerByCGLIB$$b857906a var10000 = new MacBookSeller$$EnhancerByCGLIB$$b857906a();
        CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
        return var10000;
    }

    public Object newInstance(Callback var1) {
        throw new IllegalStateException("More than one callback object required");
    }
    //创建对象的时候要传入 Callback
    public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
        CGLIB$SET_THREAD_CALLBACKS(var3);
        MacBookSeller$$EnhancerByCGLIB$$b857906a var10000 = new MacBookSeller$$EnhancerByCGLIB$$b857906a;
        //基于CallbackFilter配置来生成的不同方法设置不同的Callback
        switch(var1.length) {
        case 0:
            var10000.<init>();
            break;
        case 1:
            if (var1[0].getName().equals("java.lang.String")) {
                var10000.<init>((String)var2[0]);
                break;
            }

            throw new IllegalArgumentException("Constructor not found");
        default:
            throw new IllegalArgumentException("Constructor not found");
        }

        CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
        return var10000;
    }

    public Callback getCallback(int var1) {
        CGLIB$BIND_CALLBACKS(this);
        Object var10000;
        //基于CallbackFilter配置来生成的不同方法设置不同的Callback
        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;
        default:
            var10000 = null;
        }

        return (Callback)var10000;
    }

    public void setCallback(int var1, Callback var2) {
        switch(var1) {
        case 0:
            this.CGLIB$CALLBACK_0 = (MethodInterceptor)var2;
            break;
        case 1:
            this.CGLIB$CALLBACK_1 = (MethodInterceptor)var2;
            break;
        case 2:
            this.CGLIB$CALLBACK_2 = (NoOp)var2;
        }

    }

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

    public void setCallbacks(Callback[] var1) {
        this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0];
        this.CGLIB$CALLBACK_1 = (MethodInterceptor)var1[1];
        this.CGLIB$CALLBACK_2 = (NoOp)var1[2];
    }

    static {
        CGLIB$STATICHOOK1();
    }
}

通过生成的增强类可以分析以下几点

接下来看生成的FastClass,我们只看一个对应目标类的FastClass就可以,对应增强类的FastClass实现是类似的

public class MacBookSeller$$FastClassByCGLIB$$f1fe2621 extends FastClass {
    public MacBookSeller$$FastClassByCGLIB$$f1fe2621(Class var1) {
        super(var1);
    }

    public int getIndex(Signature var1) {
        String var10000 = var1.toString();
        switch(var10000.hashCode()) {
        case -1725733088:
            if (var10000.equals("getClass()Ljava/lang/Class;")) {
                return 8;
            }
            break;
        case -1026001249:
            if (var10000.equals("wait(JI)V")) {
                return 3;
            }
            break;
        case -819357441:
            if (var10000.equals("repairComputor(Ljava/lang/String;)Ljava/lang/String;")) {
                return 0;
            }
            break;
        case 243996900:
            if (var10000.equals("wait(J)V")) {
                return 4;
            }
            break;
        case 667760668:
            if (var10000.equals("sellComputor(Ljava/lang/String;)V")) {
                return 1;
            }
            break;
        case 946854621:
            if (var10000.equals("notifyAll()V")) {
                return 10;
            }
            break;
        case 1116248544:
            if (var10000.equals("wait()V")) {
                return 2;
            }
            break;
        case 1826985398:
            if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
                return 5;
            }
            break;
        case 1902039948:
            if (var10000.equals("notify()V")) {
                return 9;
            }
            break;
        case 1913648695:
            if (var10000.equals("toString()Ljava/lang/String;")) {
                return 6;
            }
            break;
        case 1984935277:
            if (var10000.equals("hashCode()I")) {
                return 7;
            }
        }

        return -1;
    }

    public int getIndex(String var1, Class[] var2) {
        switch(var1.hashCode()) {
        case -1886247170:
            if (var1.equals("repairComputor")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.String")) {
                        return 0;
                    }
                }
            }
            break;
        case -1776922004:
            if (var1.equals("toString")) {
                switch(var2.length) {
                case 0:
                    return 6;
                }
            }
            break;
        case -1358544445:
            if (var1.equals("sellComputor")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.String")) {
                        return 1;
                    }
                }
            }
            break;
        case -1295482945:
            if (var1.equals("equals")) {
                switch(var2.length) {
                case 1:
                    if (var2[0].getName().equals("java.lang.Object")) {
                        return 5;
                    }
                }
            }
            break;
        case -1039689911:
            if (var1.equals("notify")) {
                switch(var2.length) {
                case 0:
                    return 9;
                }
            }
            break;
        case 3641717:
            if (var1.equals("wait")) {
                switch(var2.length) {
                case 0:
                    return 2;
                case 1:
                    if (var2[0].getName().equals("long")) {
                        return 4;
                    }
                    break;
                case 2:
                    if (var2[0].getName().equals("long") && var2[1].getName().equals("int")) {
                        return 3;
                    }
                }
            }
            break;
        case 147696667:
            if (var1.equals("hashCode")) {
                switch(var2.length) {
                case 0:
                    return 7;
                }
            }
            break;
        case 1902066072:
            if (var1.equals("notifyAll")) {
                switch(var2.length) {
                case 0:
                    return 10;
                }
            }
            break;
        case 1950568386:
            if (var1.equals("getClass")) {
                switch(var2.length) {
                case 0:
                    return 8;
                }
            }
        }

        return -1;
    }

    public int getIndex(Class[] var1) {
        switch(var1.length) {
        case 0:
            return 1;
        case 1:
            if (var1[0].getName().equals("java.lang.String")) {
                return 0;
            }
        default:
            return -1;
        }
    }
    //通过不同的索引index来找到具体哪个方法的调用,避免了反射调用
    public Object invoke(int var1, Object var2, Object[] var3) throws InvocationTargetException {
        MacBookSeller var10000 = (MacBookSeller)var2;
        int var10001 = var1;

        try {
            switch(var10001) {
            case 0:
                return var10000.repairComputor((String)var3[0]);
            case 1:
                var10000.sellComputor((String)var3[0]);
                return null;
            case 2:
                var10000.wait();
                return null;
            case 3:
                var10000.wait(((Number)var3[0]).longValue(), ((Number)var3[1]).intValue());
                return null;
            case 4:
                var10000.wait(((Number)var3[0]).longValue());
                return null;
            case 5:
                return new Boolean(var10000.equals(var3[0]));
            case 6:
                return var10000.toString();
            case 7:
                return new Integer(var10000.hashCode());
            case 8:
                return var10000.getClass();
            case 9:
                var10000.notify();
                return null;
            case 10:
                var10000.notifyAll();
                return null;
            }
        } catch (Throwable var4) {
            throw new InvocationTargetException(var4);
        }

        throw new IllegalArgumentException("Cannot find matching method/constructor");
    }

    public Object newInstance(int var1, Object[] var2) throws InvocationTargetException {
        MacBookSeller var10000 = new MacBookSeller;
        MacBookSeller var10001 = var10000;
        int var10002 = var1;

        try {
            switch(var10002) {
            case 0:
                var10001.<init>((String)var2[0]);
                return var10000;
            case 1:
                var10001.<init>();
                return var10000;
            }
        } catch (Throwable var3) {
            throw new InvocationTargetException(var3);
        }

        throw new IllegalArgumentException("Cannot find matching method/constructor");
    }

    public int getMaxIndex() {
        return 10;
    }
}

主要来看invoke方法,在该方法中建立了目标类方法和index的对应关系。这样在调用的时候直接使用index就可以查找到调用哪个方法,避免了反射调用。

再来看下是在哪使用FastClass的invoke方法的,来看下MethodProxy的实现,每个方法都会创建一个MethodProxy对象,在MethodProxy对象中会分别保存对应目标类的FastClass对象和该方法对应的index,和对应增强类的FastClass对象和该方法对应的index,通过调用FastClass的invoke方法实现对方法的调用

public class MethodProxy {
    private Signature sig;
    private String superName;//父类名称,也就是增强前类的名称
    private FastClass f1;//增强前类对应生成的FastClass对象
    private FastClass f2;//增强后类对应生成的FastClass对象
    private int i1;//增强前类的某方法在FastIndex中的索引
    private int i2;//增强后类的某方法在FastIndex中的索引

//CGLIB$repairComputor$0$Proxy = MethodProxy.create(var10000, Class.forName("cn.zlz.proxy.cglib.MacBookSeller"),  Class.forName("cn.zlz.proxy.cglib.MacBookSeller$$EnhancerByCGLIB$$4780b236"), "(Ljava/lang/String;)Ljava/lang/String;", "repairComputor", "CGLIB$repairComputor$0");

    public static MethodProxy create(ClassLoader loader, Class c1, Class c2, String desc, String name1, String name2) {
        final Signature sig1 = new Signature(name1, desc);
        Signature sig2 = new Signature(name2, desc);
        FastClass f1 = helper(loader, c1);//生成增强前类的FastClass并创建对象
        FastClass f2 = helper(loader, c2);//生成增强后类的FastClass并创建对象
        int i1 = f1.getIndex(sig1);//获取增强前方法的索引
        int i2 = f2.getIndex(sig2);//获取增强后方法的索引
        MethodProxy proxy;
        if (i1 < 0) {
            proxy = new MethodProxy() {
                public Object invoke(Object obj, Object[] args) throws Throwable {
                    throw new IllegalArgumentException("Protected method: " + sig1);
                }
            };
        } else {
            proxy = new MethodProxy();
        }
        proxy.f1 = f1;
        proxy.f2 = f2;
        proxy.i1 = i1;
        proxy.i2 = i2;
        proxy.sig = sig1;
        proxy.superName = name2;
        return proxy;
    }
}

使用MethodProxy的invoke方法调用目标类的方法,在该方法中会调用目标类对应的FastClass对象的invoke方法,通过索引找到目标对象的具体方法,避免反射

public Object invoke(Object obj, Object[] args) throws Throwable {
    try {
        return f1.invoke(i1, obj, args);
    } catch (InvocationTargetException e) {
        throw e.getTargetException();
    }
}

使用MethodProxy的invokeSuper方法调用增强类的方法,在该方法中调用增强类对象的FastClass对象的invoke方法,通过索引找到具体的方法,避免反射

public Object invokeSuper(Object obj, Object[] args) throws Throwable {
    try {
        return f2.invoke(i2, obj, args);
    } catch (InvocationTargetException e) {
        throw e.getTargetException();
    }
}

源码

简单了解下cglib增强类的实现

Callback接口

CallbackFilter接口

Factory接口

Enhancer类

Enhancer类是cglib提供增强功能的入口类,通过该类可以在运行时动态创建增强类或者增强类对象

上一篇 下一篇

猜你喜欢

热点阅读