动态代理和CGLib源码探索尝试

动态代理

关于动态代理在之前的反射部分有过介绍。

动态代理

InvocationHandler

关键接口。

每个代理实例都会关联一个 invocation handler,当一个代理实例的方法被调用 ,方法调用会被编码并分发到其的 invocation handler 的 invoke 方法。

@param proxy 调用方法的代理实例

@param method 代理实例上调用的接口方法对应的{@code Method}实例。 {@code Method} 对象的声明类将是该方法声明所在的接口,该接口可以是代理类继承该方法所使用的代理接口的超接口。

@param args 包含在代理实例的方法中传递的参数值的对象数组,如果接口方法不接受参数则为{@code null}。基本数据类型的参数应为包装类的实例。

@return 返回从代理实例上的方法调用返回的值。
1. 如果接口方法声明的返回类型是基本数据类型,则该方法返回的值必须是对应包装类的实例;否则,它必须是可指派的声明的返回类型。
2. 如果此方法返回的值为 {@code null} 且接口方法的返回类型为基本数据类型,则代理实例上的方法调用将抛出 {@code NullPointerException}。如果此方法返回的值与上述接口方法声明的返回类型不兼容,则代理实例上的方法调用将抛出{@code ClassCastException}。

public Object invoke(Object proxy, Method method, Object[] args)
    throws Throwable;

Proxy.newProxyInstance()

//入参包括ClassLoader、泛型Class集合、InvocationHandler
public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
        throws IllegalArgumentException
{
    //检测 Invocation Handler 不为null
    Objects.requireNonNull(h);
    //拷贝Class集合
    final Class<?>[] intfs = interfaces.clone();
    /**
     * 获取系统安全管理器,安全管理器是一个允许应用程序实现安全策略的类
     * 它允许应用程序在执行可能不安全的操作之前确定该操作是什么,以及是否在允许执行该操作的安全上下文中尝试该操作
     * 应用程序可以允许或禁止该操作
     */
    final SecurityManager sm = System.getSecurityManager();
    /**
     * 如果安全管理器不为空,检查创建代理类所需的权限
     * 要定义一个代理类,它执行 Class.forName 中的访问检查(VM 将调用 ClassLoader.checkPackageAccess):
     *     1. "getClassLoader" 权限检查是否 loader == null
     *     2. checkPackageAccess 在它实现的接口上
     */
    if (sm != null) {
        checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
    }

    //查找或生成指定的代理类
    Class<?> cl = getProxyClass0(loader, intfs);

    //使用指定的调用处理程序调用其构造函数
    try {
        /**
         * 进行一个 newProxy 权限的查
         * 如果调用者在代理类的不同运行时包中,则进行权限检查
         */
        if (sm != null) {
            checkNewProxyPermission(Reflection.getCallerClass(), cl);
        }

        //通过Class cl来获取 Constructor,constructorParams 是Proxy类中静态规定的 InvocationHandler.class
        final Constructor<?> cons = cl.getConstructor(constructorParams);
        final InvocationHandler ih = h;
        //如果 cl.getModifiers()获取修饰符非public,通过 setAccessible() 使其可修改
        if (!Modifier.isPublic(cl.getModifiers())) {
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                public Void run() {
                    cons.setAccessible(true);
                    return null;
                }
            });
        }
        //传入 InvocationHandler 实例去构造一个代理类的实例,通过cons.newInstance()创建实例并返回
        return cons.newInstance(new Object[]{h});
    } catch (IllegalAccessException|InstantiationException e) {
        throw new InternalError(e.toString(), e);
    } catch (InvocationTargetException e) {
        Throwable t = e.getCause();
        if (t instanceof RuntimeException) {
            throw (RuntimeException) t;
        } else {
            throw new InternalError(t.toString(), t);
        }
    } catch (NoSuchMethodException e) {
        throw new InternalError(e.toString(), e);
    }
}

newProxyInstance() 方法包括进行权限、合法性检测,调用 getProxyClass0(loader, intfs) 获取 Class<?> cl ,再通过 cl 对实例进行创建,主要还是通过反射机制。

intfs = interfaces

intfs + loader ==> Class<?> cl ==> Constructor<?> cons + InvocationHandler h ==> Object

/**
 * 生成代理类。在调用此方法之前,必须调用 checkProxyAccess 方法来执行权限检查
 */
private static Class<?> getProxyClass0(ClassLoader loader,
                                       Class<?>... interfaces) {
    if (interfaces.length > 65535) {
        throw new IllegalArgumentException("interface limit exceeded");
    }

    /**
     * 如果由  实现给定接口的加载器  定义的代理类存在,将简单地返回缓存副本
     * 否则,它将通过 ProxyClassFactory 创建代理类
     */
    return proxyClassCache.get(loader, interfaces);
}
/**
 * 此方法存在于 java.lang.reflect.WeakCache 类中
 * 通过缓存查找值。总是评估 {@code subKeyFactory} 函数
 * 如果缓存中没有给定 (key, subKey) 对的条目或者条目已经被清除,则可选地评估 {@code valueFactory} 函数。
 */
public V get(K key, P parameter) {
    //判定 parameter 不为null
    Objects.requireNonNull(parameter);

    /**
     * 删除陈旧的条目,持续从  ReferenceQueue<K> refQueue 中取出 cacheKey
     * 将 key 为对应 CacheKey 的条目从 map 中移除 (map 的结构为 ConcurrentMap<?, ? extends ConcurrentMap<?, ?>> )
     * map 中 通过 key 可以获取对应的 valuesMap
     * 遍历 valuesMap 所包含的 values() 集合,cacheValue 若为 reverseMap 中的 key
     * 则将其k-v对从 reverseMap 中移除 (reverseMap 的结构为 ConcurrentMap<?, Boolean> )
     */
    expungeStaleEntries();

    //若 key 不为 null,通过 new CacheKey(key, refQueue) 创建新的 CacheKey 实例
    Object cacheKey = CacheKey.valueOf(key, refQueue);

    //为特定的 cacheKey 懒加载第二级 valuesMap
    ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
    //如果一级 map 中不存在相应的 cacheKey - valuesMap 条目
    if (valuesMap == null) {
        //如果传入 cacheKey 已经存在,就返回。如果不存在,就添加键值对 ,返回null
        ConcurrentMap<Object, Supplier<V>> oldValuesMap
                = map.putIfAbsent(cacheKey,
                valuesMap = new ConcurrentHashMap<>());
        //map 中已存在 cacheKey 的情况,将 valuesMap 置为获取到的 oldValuesMap
        if (oldValuesMap != null) {
            valuesMap = oldValuesMap;
        }
    }

    //创建 subKey 并从 valuesMap 中检索该 subKey 存储的可能的 Supplier<V>
    Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
    Supplier<V> supplier = valuesMap.get(subKey);
    Factory factory = null;

    /**
     * 循环部分的整体思路为:
     *     1.supplier 判空,或获取value失败
     *     2.懒构建 factory
     *     3.supplier 为空:将subKey-factory传入 valuesMap
     *     4.supplier 不为空:将 subKey 对应的 supplier 替换成 factory 或 再次尝试获取 supplier
     */
    while (true) {
        if (supplier != null) {
            //supplier 可能是 Factory 或 CacheValue<V> 实例
            V value = supplier.get();
            if (value != null) {
                return value;
            }
        }
        //否则,缓存中没有 supplier 
        //或返回的 supplier 为 null (可能是清除的 CacheValue 或未成功安装 CacheValue 的工厂)

        //懒构建工厂,一个工厂 {@link Supplier},它实现了值的延迟同步构造并将其安装到缓存中。
        if (factory == null) {
            factory = new Factory(key, parameter, subKey, valuesMap);
        }

        //supplier 为空时,将 subKey-factory作为键值对传入 valuesMap,成功则将 factory 赋值给 supplier
        if (supplier == null) {
            supplier = valuesMap.putIfAbsent(subKey, factory);
            if (supplier == null) {
                //成功配置工厂
                supplier = factory;
            }
            //supplier 不为空,说明 valuesMap 中 subKey 已有对应的 supplier,将 subKey 对应的 supplier 替换
        } else {
            if (valuesMap.replace(subKey, supplier, factory)) {
                //成功地用我们的工厂替换了清除的 缓存条目/不成功的工厂
                supplier = factory;
            } else {
                //再次获取 supplier
                supplier = valuesMap.get(subKey);
            }
        }
    }
}

CGLib使用和源码

学习用例

先给出使用 CGLib 实现动态代理的 Examples。

public class TargetObject {
    public String method1(String string) {
        System.out.println(string);
        return string;
    }

    public int method2(int i1) {
        System.out.println(i1);
        return i1;
    }

    public int method3(int i2) {
        System.out.println(i2);
        return i2;
    }

    @Override
    public String toString() {
        return "CglibInterceptor.TargetObject : "+ getClass();
    }
}
/**
 * @description: 自定义继承 MethodInterceptor 创建拦截器
 * 调用目标函数时,CGLib 回调 Interceptor 实现自定义代理逻辑
 *
 * invokeSuper:
 *   1. init()
 *      <!-- 使用 volatile 不变量允许我们以原子方式初始化 FastClass 和方法索引对 --!>
 *      1.1. 创建 CreateInfo
 *      CreateInfo:
 *          Class c1;
 *          Class c2;
 *
 *      1.2. 创建 FastClassInfo
 *      内部静态类 FastClassInfo:
 *             FastClass f1;
 *             FastClass f2;
 *             int i1;  f1 的 index
 *             int i2;  f2 的 index
 *         抽象类 FastClass:
 *             Class type;
 *             getIndex(): 返回匹配方法的索引。(之后可以使用该索引以较少的开销调用该方法)
 *             invoke(): 调用 Method (用指定 Index)
 *
 *      1.3. 调用 helper() 给 f1、f2 赋值
 *      helper(CreateInfo ci, Class type) 方法会将 ClassLoader 都设置为 ci.c2.getClassLoader()
 *      设置对应参数,创建 FastClass.Generator,再调用 create() 方法创建 FastClass 返回
 *
 *   2. 获得 FastClassInfo
 *   3. 调用 FastClassInfo.f2.invoke() 并返回结果
 */
public class TargetInterceptor implements MethodInterceptor {
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("调用前...");
        Object result = methodProxy.invokeSuper(o, objects);
        System.out.println("调用后...");
        return result;
    }
}
/**
 * @description: 表示锁定方法返回值,无论被代理类的方法返回什么值,回调方法都返回固定值
 * 该类实现FixedValue接口,同时锁定回调值为999
 * (整型,CallbackFilter 中定义的使用 FixedValue 型回调的方法为 getConcreteMethodFixedValue
 * 该方法返回值为整型)
 */
public class TargetResultFixed implements FixedValue {
    public Object loadObject() throws Exception {
        System.out.println("锁定结果");
        Object obj = 999;
        return obj;
    }
}
/**
 * @description: 在CGLib回调时可以设置对不同方法执行不同的回调逻辑,或者根本不执行回调。
 */
public class TargetMethodCallbackFilter implements CallbackFilter {
    public int accept(Method method) {
        if(method.getName().equals("method1")){
            System.out.println("Filter method1 index == 0");
            return 0;
        }
        if(method.getName().equals("method2")){
            System.out.println("Filter method2 index == 1");
            return 1;
        }
        if(method.getName().equals("method3")){
            System.out.println("Filter method3 index == 2");
            return 2;
        }
        return 0;
    }
}
public class TestCglib {
    public static void main(String[] args) {
        //Enhancer CGLib中的一个字节码增强器
        Enhancer enhancer =new Enhancer();
        enhancer.setSuperclass(TargetObject.class);
        //例1
        //enhancer.setCallback(new CglibInterceptor.TargetInterceptor());

        //例2
        /**
         * (1)callback1: 方法拦截器
         * (2)NoOp.INSTANCE: NoOp表示 No Operation,代理类直接调用被代理的方法不进行拦截。
         * (3)FixedValue: 表示锁定方法返回值,无论被代理类的方法返回什么值,回调方法都返回固定值。
         */
        CallbackFilter callbackFilter = new TargetMethodCallbackFilter();
        Callback noopCb = NoOp.INSTANCE;
        Callback callback1 = new TargetInterceptor();
        Callback fixedValue = new TargetResultFixed();
        //这里 0代表 callback1,1代表直接调用方法不拦截,2代表过滤器强制修改返回值
        Callback[] cbarray = new Callback[]{callback1,noopCb,fixedValue};
        enhancer.setCallbacks(cbarray);
        enhancer.setCallbackFilter(callbackFilter);

        TargetObject targetObject=(TargetObject)enhancer.create();
        //System.out.println(targetObject);
        System.out.println("<--------->");
        System.out.println(targetObject.method1("method1"));
        System.out.println("<--------->");
        System.out.println(targetObject.method2(222));
        System.out.println("<--------->");
        System.out.println(targetObject.method3(333));
    }
}

CGLib源码分析

上面列出了 FastClass 和对应的 FastClassInfo,并且 FastClassInfo 内部包含了两个 FastClass,源码中 MethodProxy 的 create(…) 中也包含了 c1 和 c2 两个 Class 实例。 MethodProxy 中 invoke 方法如下:

public Object invoke(Object obj, Object[] args) throws Throwable {
        ......


        init();
        FastClassInfo fci = fastClassInfo;
        return fci.f1.invoke(fci.i1, obj, args);

        ......
}


public Object invokeSuper(Object obj, Object[] args) throws Throwable {
        ......

        init();
        FastClassInfo fci = fastClassInfo;
        return fci.f2.invoke(fci.i2, obj, args);


        ......
}

其中,f1 为动态代理类FastClass,f2 为被代理类的FastClass。i1, i2 则为 method 对应的 index。

首先要了解的是,CGLib 设计了 ClassGenerator 接口作为最基础的接口之一,放在 cglib.core 下。

ClassGenerator 中仅声明了一个方法:

public interface ClassGenerator {
    void generateClass(ClassVisitor v) throws Exception;
}

其中,入参 ClassVisitor v 为 ASM 定义的接口(CGLib 是基于 ASM 对字节码进行操作),暂不引申。

抽象类 AbstractClassGenerator 是对 ClassGenerator 接口进一步细化,它定义了一些较为关键的属性,比如 GeneratorStrategy、ClassLoader、类名、Source(内部类,核心属性为 WeakHashMap,用作缓存)等。

FastClass 中声明了静态内部类 Generator,继承了 AbstractClassGenerator。

//AbstractClassGenerator
abstract public class AbstractClassGenerator implements ClassGenerator {
    private static final Object NAME_KEY = new Object();
    private static final ThreadLocal CURRENT = new ThreadLocal();

    private GeneratorStrategy strategy = DefaultGeneratorStrategy.INSTANCE;
    private NamingPolicy namingPolicy = DefaultNamingPolicy.INSTANCE;
    private net.sf.cglib.core.AbstractClassGenerator.Source source;
    private ClassLoader classLoader;
    private String namePrefix;
    private Object key;
    private boolean useCache = true;
    private String className;
    private boolean attemptLoad;

    ......

    protected static class Source {
        String name;
        Map cache = new WeakHashMap();

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

    ......

}
//FastClass 静态内部类 Generator
public static class Generator extends AbstractClassGenerator {
    private static final Source SOURCE = new Source(FastClass.class.getName());
    private Class type;

    public Generator() {
        super(SOURCE);
    }

    ......

    protected ClassLoader getDefaultClassLoader() {
        return type.getClassLoader();
    }

    public void generateClass(ClassVisitor v) throws Exception {
        new FastClassEmitter(v, getClassName(), type);
    }

    ......

}

FastClass 的 create() 方法调用内部类 Generator 的父类 AbstractClassGenerator 中的 create(Object key) 方法。

protected Object create(Object key) {
    try {
        Class gen = null;

        //Source 内部是一个名为 cache 的 WeakHashMap() 和名为 name 的String
        synchronized (source) {
            //获取当前类加载器,$AppClassLoader
            ClassLoader loader = getClassLoader();
            //建立二级缓存,并尝试获取 source 中是否还有二级缓存
            Map cache2 = null;
            cache2 = (Map)source.cache.get(loader);
            /**
             * 如果二级缓存为空,创建新的 HashMap,将 NAME_KEY 和 HashSet 的键值对存入
             * 并将二级缓存放入以 loader 为 key 的缓存中
             */
            if (cache2 == null) {
                cache2 = new HashMap();
                cache2.put(NAME_KEY, new HashSet());
                source.cache.put(loader, cache2);
            //useCache: 针对具有相同属性的类,是否使用和更新生成类的静态缓存。
            } else if (useCache) {
                //获取二级缓存中 key 对应的 Reference
                Reference ref = (Reference)cache2.get(key);
                //如果 ref 不为空,则把 T类型赋给 gen,再转 Class
                gen = (Class) (( ref == null ) ? null : ref.get());
            }
            //通过 ThreadLocal CURRENT 规避多线程访问出现线程不安全
            if (gen == null) {
                //从 CURRENT 中获取此线程局部变量的当前线程副本中的值
                Object save = CURRENT.get();
                //将当前类设置为线程局部变量的当前线程副本中的值
                CURRENT.set(this);
                try {
                    //将入参 key 赋值给类中的 key
                    this.key = key;
                    /**
                     * attemptLoad 如果设置,CGLIB 将在生成 Classes 之前
                     * 尝试从指定的 ClassLoader 加载这些 Classes
                     * 因为不能保证生成的类名是唯一的,所以默认为 false
                     */
                    if (attemptLoad) {
                        try {
                            //尝试加载指定类
                            gen = loader.loadClass(getClassName());
                        } catch (ClassNotFoundException e) {
                            // ignore
                        }
                    }
                    //如果 attemptLoad 为 false 或 尝试加载失败,gen 依然为 null
                    if (gen == null) {
                        /**
                         * GeneratorStrategy 负责获取 ClassGenerator 并生成一个字节数组,包含生成的 Class 的数据
                         * 通过提供自定义策略可以在加载之前检查或修改生成的类
                         * 通常将通过子类化 DefaultGeneratorStrategy 并覆盖适当的受保护方法来实现
                         */
                        byte[] b = strategy.generate(this);
                        /**
                         * 从字节数组中读取 className
                         * 获取 className ,并添加 className 到二级缓存中 NAME_KEY 对应的 HashSet 
                         */
                        String className = ClassNameReader.getClassName(new ClassReader(b));
                        getClassNameCache(loader).add(className);
                        /**
                         * ReflectUtils.defineClass() 方法内部调用 DEFINE_CLASS.invoke()
                         * 且 DEFINE_CLASS 由 ClassLoader.getDeclaredMethod("defineClass"...) 获取
                         * 即将字节码传入,调用 ClassLoader.defineClass() 方法动态生成 Class
                         */
                        gen = ReflectUtils.defineClass(className, b, loader);
                    }
                    //将 key 和创建实例的弱引用放入二级缓存
                    if (useCache) {
                        cache2.put(key, new WeakReference(gen));
                    }
                    //调用 firstInstance(),传入 Class,通过反射获取该 Class 的实例
                    return firstInstance(gen);
                } finally {
                    CURRENT.set(save);
                }
            }
        }
        return firstInstance(gen);
    } catch (RuntimeException e) {
        throw e;
    } catch (Error e) {
        throw e;
    } catch (Exception e) {
        throw new CodeGenerationException(e);
    }
}

关于缓存部分,一级缓存中的键 loader 为 AppClassLoader,二级缓存中的键为 Object。

如果二级缓存不存在,则创建二级缓存,放入一组新键值对{以 private static final Object 为键,new HashSet() 为值}。二级缓存中存放的 HashSet 用作存储 className。

如果允许使用缓存(useCache 为 true),则 Class gen 从二级缓存中取出,通过 reference.get() 获取 T(Class)。主要通过通过 firstInstance(gen) 创建实例。

调试调用方法

注释掉 TestCglib 中对 method2 和 method3 的调用,给最底层的 create() 方法打一个断点,观察 gen 值的变化。

1
1
进行到 Enhancer enhancer  = new Enhancer(); 时,会产生第一次调用。
是由 EnhancerKey 中的 KEY_FACTORY 在初始化时调用的。
传入的 Object key: "net.sf.cglib.proxy.Enhancer$EnhancerKey"
第一次调用结束前,gen 为 "net.sf.cglib.proxy.Enhancer$EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72"

并且,在二级缓存中创建 HashSet 并将生成的 EnhancerKey$$KeyFactoryByCGLIB 全名记录,在二级缓存中存入 EnhancerKey 的弱引用依赖。
2
2
进行到 TargetObject targetObject=(TargetObject)enhancer.create(); 时,会产生多次 create() 方法调用。
本次路径为: 
Enhancer.create() -> createHelper() -> super.create() -> {create()}

传入的 Object key 为上面产生的 "EnhancerKey$$KeyFactoryByCGLIB$$7fb24d72"
可以在它的 FIELD_3 中观察到,与DEMO中定义的过滤器顺序相同
Callback[] cbarray = new Callback[]{callback1,noopCb,fixedValue};
3
3
进行到 TargetObject targetObject=(TargetObject)enhancer.create(); 时,会产生多次 create() 方法调用。
本次路径为: 
Enhancer.create() -> createHelper() -> super.create() -> {create()} -> strategy.generate() ->
transform() -> getMethod() -> MethodWrapper.createSet(interfaceMethods) -> 
MethodWrapperKey KEY_FACTORY 初始化 -> {create()}

传入的 Object key 为 "net.sf.cglib.core.MethodWrapper$MethodWrapperKey"
调用结束前,gen 为 
"class net.sf.cglib.core.MethodWrapper$MethodWrapperKey$$KeyFactoryByCGLIB$$d45e49f7"

可以看到二级缓存中已经按顺序存放了 CGLib 生成的 EnhancerKey$$KeyFactoryByCGLIB 和 MethodWrapperKey$$KeyFactoryByCGLIB,且在二级缓存中存放的 HashSet 中储存了其对象名,用于之后判重。
3 是嵌套在 2 中的,当 3 返回 MethodWrapper 对象后退出,Enhancer 对象被放入ThreadLocal CURRENT 中。这时程序由如下代码后继续运行:
byte[] b = strategy.generate(this);
即由字节码创建 Class 类并返回。
注意,这里 cache 和 3 中的 HashMap 并不是同一个。调用一次完全顺序执行,记录值如下{key,this,cache2}: 
1    Enhance$EnhancerKey             this {KeyFactory$Generator@510}  cache2 {HashMap@520}
2    EnhancerKey$$KeyFactoryByCGLIB  this {Enhancer@591}              cache2 {HashMap@605}
3    MethodWrapper$$MethodWrapperKey this {KeyFactory$Generator@612}  cache2 {HashMap@520}
OUT  EnhancerKey$$KeyFactoryByCGLIB  this {Enhancer@591}              cache2 {HashMap@605}
4    CglibInterceptor.TargetObject   this {FastClass$Generator@657}   cache2 {HashMap@662}
5    TargetObject$$EnhancerByCGLIB   this {FastClass$Generator@677}   cache2 {HashMap@662}

由 4、5 发现两个 FastClass 并不相同,且传入的 key 分别为 初始类型 TargetObject 和 增强类型 TargetObject$$EnhancerByCGLIB。

4
4
本次路径为:
invokeSuper() -> init() -> helper() -> create()

传入的 key 为 "CglibInterceptor.TargetObject"
调用结束前,gen 为 "class CglibInterceptor.TargetObject$$FastClassByCGLIB$$eea6ba1a"
即由初始类型获得被 FastClass 处理过的类型。
5
5
本次路径为:
invokeSuper() -> init() -> helper() -> create()

传入的 key 为 "CglibInterceptor.TargetObject$$EnhancerByCGLIB$$5cb10b5e"
调用结束前,gen 为 
"class CglibInterceptor.TargetObject$$EnhancerByCGLIB$$5cb10b5e$$FastClassByCGLIB$$3bf704cb"
即由 Enhancer 加强后的对象再由 FastClass 进行一次包装。

FastClass 是用于统一操作的结构,作用是根据 index 调用对应的 method 而不使用反射获取。传入 TargetObject 和 TargetObject$$EnhancerByCGLIB 即为被代理类和代理类。对应会建立被代理类和代理类的 FastClass 。

回到开头介绍的 FastClassInfo 中,包含的两个 FastClass,且 invokeSuper() 内部为调用 fci.f2.invoke(),即为调用代理类的 FastClass 的对应方法。那为什么要设立 invokeSuper() 和 invoke() 两种方法呢?

invokeSuper() 和 invoke() 的调用逻辑

对Demo中的 TargetInterceptor 类进行一个小修改,如下:

//修改前
Object result = methodProxy.invokeSuper(o, objects);
//修改后
Object result = methodProxy.invoke(o, objects);

运行后会产生如下结果:


调用前...
调用前...
调用前...
调用前...
调用前...
调用前...
...
Exception in thread "main" java.lang.StackOverflowError

出现多个函数调用前的打印信息,但没有出现 “调用后…” ,最后报错栈溢出。可以确定是循环嵌套调用 intercept() 方法。换句话说,methodProxy.invoke(o, objects) 会不停的调用到 intercept(),而methodProxy.invokeSuper(o, objects) 不会产生这样的情况。

上面提到,invokeSuper() 和 invoke() 方法的差距仅为调用的 FastClass 不同,所以关键原因即在TargetObject$$FastClassByCGLIB$$eea6ba1a 和 TargetObject$$EnhancerByCGLIB$$5cb10b5e$$FastClassByCGLIB$$3bf704cb 上。

invokeSuper()
invoke()