CGLib

1. Enhancer

Enhancer是JDK动态代理的替代方法,既可以代理接口,又可以代理类。

Enhancer动态生成代理类,继承委托基类或实现委托接口,覆盖委托基类的非final方法,并将方法的调用转发到用户自定义的拦截器(继承Callback)。

public class Enhancer {

    // 设置委托基类
    void setSuperclass(Class superclass);

    // 设置委托接口
    void setInterfaces(Class[] interfaces);

    // 设置拦截器:所有方法转发到同一拦截器
    void setCallback(final Callback callback);

    // 设置多个拦截器
    void setCallbacks(Callback[] callbacks);
    // 设置方法拦截器映射:哪个方法的调用转发到哪个拦截器
    void setCallbackFilter(CallbackFilter filter);

    // 通过无参构造方法创建代理子类实例
    Object create();
    // 通过有参构造方法创建代理子类实例
    Object create(Class[] argumentTypes, Object[] arguments);

    // 方法在构造方法中被调用时是否被拦截,默认是
    void setInterceptDuringConstruction(boolean interceptDuringConstruction);
}

2. MethodInterceptor

所有的拦截器都实现Callback接口,最常用的拦截器是MethodInterceptor,提供“around advice”。

public interface MethodInterceptor extends Callback {

    /**
     * 委托方法被调用时转发到此
     *
     * @param obj    代理子类实例
     * @param method 委托类方法反射
     * @param args   方法参数对象
     * @param proxy  用于调用原方法,见第3节
     */
    Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy);
}

3. MethodProxy

用来调用代理子类中的基类方法副本,或委托基类中的原方法。

public class MethodProxy {

    /**
     * 调用代理子类中的基类方法副本(通过super调用委托基类原方法)
     *
     * @param proxyInstance   代理子类实例,
     *                        必须是传给MethodInterceptor.intercept方法的第一个参数对象
     * @param parameterValues 方法参数对象,
     *                        可以是传给MethodInterceptor.intercept方法的第三个参数对象,
     *                        也可以使用类型兼容的其他对象数组
     */
    Object invokeSuper(Object obj, Object[] args);

    /**
     * 调用基类中的原始方法
     *
     * @param superInstance   委托基类实例,
     *                        不能是传给MethodInterceptor.intercept方法的第一个参数对象,
     *                        否则会导致循环调用
     * @param parameterValues 方法参数对象,
     *                        可以是传给MethodInterceptor.intercept方法的第三个参数对象,
     *                        也可以使用类型兼容的其他对象数组
     */
    Object invoke(Object superInstance, Object[] parameterValues);
}

4. CallbackFilter

当对委托基类不同方法实施不同的拦截时,将方法与拦截器映射起来

public interface CallbackFilter {
    /*
     * @param method 委托基类方法
     * @return  传给Enhancer的Callback数组的下标,即映射到该拦截器
     */
    int accept(Method method);
}

5. 示例

  • 委托类
public class DelegateClass {

    public DelegateClass() {
    }

    public DelegateClass(String string) {
    }

    public boolean add(String string, int i) {
        System.out.println("This is add method: " + string + ", " + i);
        return true;
    }

    public void update() {
        System.out.println("This is update method");
    }
}
  • 拦截器1
public class LogInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object proxyInstance, Method superMethod, Object[] parameterValues, MethodProxy methodProxy) throws Throwable {
        // 打印代理子类类名
        System.out.println("obj: " + proxyInstance.getClass().getCanonicalName());
        // 打印委托基类方法名
        System.out.println("method: " + superMethod.getDeclaringClass() + "." + superMethod.getName());
        // 打印参数对象
        for (int i = 0; i < parameterValues.length; i++) {
            System.out.println("args[" + i + "]: " + parameterValues[i]);
        }
        // 调用原始方法
        Object result = methodProxy.invokeSuper(proxyInstance, args);
        // 返回调用结果
        return result;
    }
}
  • 拦截器2
public class TimeInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(Object proxyInstance, Method superMethod, Object[] parameterValues, MethodProxy methodProxy) throws Throwable {
        long startTime = System.nanoTime();
        // 调用原始方法
        Object result = methodProxy.invokeSuper(proxyInstance, parameterValues);
        // 打印耗时
        System.out.println(superMethod.getName() + " cost " + (System.nanoTime() - startTime) + " ns.");
        // 返回调用结果
        return result;
    }
}
  • 拦截映射
public class InterceptorFilter implements CallbackFilter {

    @Override
    public int accept(Method method) {
        String methodName = method.getName();
        if (methodName.equals("update")) {
            return 1;
        }
        return 0;
    }
}
  • 测试
public static void main(String[] args) {
    // 保存生成的代理子类Class文件
    System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\Temp\\CGLib");

    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(DelegateClass.class);
    // 多种拦截
    enhancer.setCallbacks(new Callback[]{new LogInterceptor(), new TimeInterceptor(), NoOp.INSTANCE});
    // 方法与拦截之间的映射
    enhancer.setCallbackFilter(new InterceptorFilter());
    // 构造器中调用方法不被拦截
    enhancer.setInterceptDuringConstruction(false);

    DelegateClass delegateInstance = (DelegateClass) enhancer.create();
    delegateInstance.add("Tom", 30);
    delegateInstance.update();
}

结果:

// add方法:
obj: com.gitee.limaozhi.study.cglib.DelegateClass$$EnhancerByCGLIB$$6e97598c
method: class com.gitee.limaozhi.study.cglib.DelegateClass.add
args[0]: Tom
args[1]: 30
This is add method: Tom, 30

// update方法:
This is update method
update cost 217512 ns.

6. 生成的代理子类

// 生成的代理子类继承委托基类,并实现Factory接口
public class DelegateClass$$EnhancerByCGLIB$$147414ed extends DelegateClass implements Factory {

    // 拦截器数组
    private static final Callback[] CGLIB$STATIC_CALLBACKS;
    
    // 拦截器映射
    private static Object CGLIB$CALLBACK_FILTER;

    // 拦截无参方法时传入的空对象数组参数
    private static final Object[] CGLIB$emptyArgs;

    // 调用委托基类DelegateClass的add方法
    // 调用基类方法:反射
    private static final Method CGLIB$add$0$Method;
    // 调用基类方法:MethodProxy
    // 两种方式:委托基类FastClass 或 代理子类FastClass + super
    private static final MethodProxy CGLIB$add$0$Proxy;

    // 调用委托基类DelegateClass的update方法
    private static final Method CGLIB$update$1$Method;
    private static final MethodProxy CGLIB$update$1$Proxy;

    // 调用Object的equals方法
    private static final Method CGLIB$equals$2$Method;
    private static final MethodProxy CGLIB$equals$2$Proxy;

    // 调用Object的toString方法
    private static final Method CGLIB$toString$3$Method;
    private static final MethodProxy CGLIB$toString$3$Proxy;

    // 调用Object的hashCode方法
    private static final Method CGLIB$hashCode$4$Method;
    private static final MethodProxy CGLIB$hashCode$4$Proxy;

    // 调用Object的clone方法
    private static final Method CGLIB$clone$5$Method;
    private static final MethodProxy CGLIB$clone$5$Proxy;


    // 为每个代理子类实例分别设置拦截器引用
    // 而不是直接使用代理子类的拦截器
    private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
    // 拦截器1
    private MethodInterceptor CGLIB$CALLBACK_0;
    // 拦截器2
    private MethodInterceptor CGLIB$CALLBACK_1;
    // 拦截器3
    private NoOp CGLIB$CALLBACK_2;
    // 代理子类实例是否已设置好拦截器
    private boolean CGLIB$BOUND;

    // 代理子类实例是否已构建好,用于判断方法被调用时是否要拦截
    // 设置为方法在构造方法中被调用时不拦截
    private boolean CGLIB$CONSTRUCTED;

    // 类初始化
    static {
        CGLIB$STATICHOOK1();
    }

    static void CGLIB$STATICHOOK1() {
        CGLIB$THREAD_CALLBACKS = new ThreadLocal();
        CGLIB$emptyArgs = new Object[0];

        // 代理子类Class
        Class proxyClass = Class.forName("DelegateClass$$EnhancerByCGLIB$$147414ed");

        // 代理子类要拦截的基类DelegateClass中的方法:add, update
        Class superClass = Class.forName("DelegateClass")
        Method[] interceptMethods = ReflectUtils.findMethods(
                new String[]{
                        "add", "(Ljava/lang/String;I)Z",
                        "update", "()V"}, superClass.getDeclaredMethods());

        CGLIB$add$0$Method = interceptMethods[0];
        CGLIB$add$0$Proxy = MethodProxy.create(superClass, proxyClass, "(Ljava/lang/String;I)Z", "add", "CGLIB$add$0");

        CGLIB$update$1$Method = interceptMethods[1];
        CGLIB$update$1$Proxy = MethodProxy.create(superClass, proxyClass, "()V", "update", "CGLIB$update$1");

        // 代理子类要拦截的基类Object中的方法:equals, toString, hashCode, clone
        superClass = Class.forName("java.lang.Object");
        interceptMethods = ReflectUtils.findMethods(
                new String[]{
                        "equals", "(Ljava/lang/Object;)Z",
                        "toString", "()Ljava/lang/String;",
                        "hashCode", "()I",
                        "clone", "()Ljava/lang/Object;"},
                superClass.getDeclaredMethods());

        CGLIB$equals$2$Method = interceptMethods[0];
        CGLIB$equals$2$Proxy = MethodProxy.create(superClass, proxyClass, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$2");

        CGLIB$toString$3$Method = interceptMethods[1];
        CGLIB$toString$3$Proxy = MethodProxy.create(superClass, proxyClass, "()Ljava/lang/String;", "toString", "CGLIB$toString$3");

        CGLIB$hashCode$4$Method = interceptMethods[2];
        CGLIB$hashCode$4$Proxy = MethodProxy.create(superClass, proxyClass, "()I", "hashCode", "CGLIB$hashCode$4");

        CGLIB$clone$5$Method = interceptMethods[3];
        CGLIB$clone$5$Proxy = MethodProxy.create(superClass, proxyClass, "()Ljava/lang/Object;", "clone", "CGLIB$clone$5");
    }

    /**
     * 覆盖基类方法DelegateClass.add,进行拦截
     */
    @Override
    public final boolean add(String var1, int var2) {
        if (!this.CGLIB$CONSTRUCTED) {
            // 在构造方法中被调用,不拦截
            return super.add(var1, var2);
        } else {
            // 拦截器1
            MethodInterceptor callback = this.CGLIB$CALLBACK_0;
            if (this.CGLIB$CALLBACK_0 == null) {
                CGLIB$BIND_CALLBACKS(this);
                callback = this.CGLIB$CALLBACK_0;
            }

            if (callback != null) {
                // 转发到拦截器intercept方法
                Object result = callback.intercept(this, CGLIB$add$0$Method, new Object[]{var1, new Integer(var2)}, CGLIB$add$0$Proxy);
                return result == null ? false : (Boolean) result;
            } else {
                return super.add(var1, var2);
            }
        }
    }
    /**
     * 基类方法副本,在原方法名上冠以前后缀
     *
     * MethodProxy在invokeSuper()中通过代理类的FastClass调用此方法,
     * 此方法通过super调用基类方法,最终达到以非反射方式调用原始方法的目的。
     */
    final boolean CGLIB$add$0(String var1, int var2) {
        return super.add(var1, var2);
    }

    @Override
    public final void update() {
        if (!this.CGLIB$CONSTRUCTED) {
            super.update();
        } else {
            MethodInterceptor callback = this.CGLIB$CALLBACK_1;
            if (this.CGLIB$CALLBACK_1 == null) {
                CGLIB$BIND_CALLBACKS(this);
                callback = this.CGLIB$CALLBACK_1;
            }

            if (callback != null) {
                callback.intercept(this, CGLIB$update$1$Method, CGLIB$emptyArgs, CGLIB$update$1$Proxy);
            } else {
                super.update();
            }
        }
    }
    final void CGLIB$update$1() {
        super.update();
    }

    @Override
    public final boolean equals(Object var1) {
        if (!this.CGLIB$CONSTRUCTED) {
            return super.equals(var1);
        } else {
            MethodInterceptor callback = this.CGLIB$CALLBACK_0;
            if (this.CGLIB$CALLBACK_0 == null) {
                CGLIB$BIND_CALLBACKS(this);
                callback = this.CGLIB$CALLBACK_0;
            }

            if (callback != null) {
                Object result = callback.intercept(this, CGLIB$equals$2$Method, new Object[]{var1}, CGLIB$equals$2$Proxy);
                return result == null ? false : (Boolean) result;
            } else {
                return super.equals(var1);
            }
        }
    }
    final boolean CGLIB$equals$2(Object var1) {
        return super.equals(var1);
    }

    @Override
    public final String toString() {
        if (!this.CGLIB$CONSTRUCTED) {
            return super.toString();
        } else {
            MethodInterceptor callback = this.CGLIB$CALLBACK_0;
            if (this.CGLIB$CALLBACK_0 == null) {
                CGLIB$BIND_CALLBACKS(this);
                callback = this.CGLIB$CALLBACK_0;
            }

            return callback != null ?
                    (String) callback.intercept(this, CGLIB$toString$3$Method, CGLIB$emptyArgs, CGLIB$toString$3$Proxy)
                    : super.toString();
        }
    }
    final String CGLIB$toString$3() {
        return super.toString();
    }

    @Override
    public final int hashCode() {
        if (!this.CGLIB$CONSTRUCTED) {
            return super.hashCode();
        } else {
            MethodInterceptor callback = this.CGLIB$CALLBACK_0;
            if (this.CGLIB$CALLBACK_0 == null) {
                CGLIB$BIND_CALLBACKS(this);
                callback = this.CGLIB$CALLBACK_0;
            }

            if (callback != null) {
                Object result = callback.intercept(this, CGLIB$hashCode$4$Method, CGLIB$emptyArgs, CGLIB$hashCode$4$Proxy);
                return result == null ? 0 : ((Number) result).intValue();
            } else {
                return super.hashCode();
            }
        }
    }
    final int CGLIB$hashCode$4() {
        return super.hashCode();
    }

    @Override
    protected final Object clone() throws CloneNotSupportedException {
        if (!this.CGLIB$CONSTRUCTED) {
            return super.clone();
        } else {
            MethodInterceptor callback = this.CGLIB$CALLBACK_0;
            if (this.CGLIB$CALLBACK_0 == null) {
                CGLIB$BIND_CALLBACKS(this);
                callback = this.CGLIB$CALLBACK_0;
            }

            return callback != null ? callback.intercept(this, CGLIB$clone$5$Method, CGLIB$emptyArgs, CGLIB$clone$5$Proxy) : super.clone();
        }
    }
    final Object CGLIB$clone$5() throws CloneNotSupportedException {
        return super.clone();
    }

    /**
     * 通过方法签名找到方法的MethodProxy
     */
    public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
        String var10000 = var0.toString();
        switch (var10000.hashCode()) {
            case -1949253108:
                if (var10000.equals("update()V")) {
                    return CGLIB$update$1$Proxy;
                }
                break;
            case -508378822:
                if (var10000.equals("clone()Ljava/lang/Object;")) {
                    return CGLIB$clone$5$Proxy;
                }
                break;
            case 837540553:
                if (var10000.equals("add(Ljava/lang/String;I)Z")) {
                    return CGLIB$add$0$Proxy;
                }
                break;
            case 1826985398:
                if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
                    return CGLIB$equals$2$Proxy;
                }
                break;
            case 1913648695:
                if (var10000.equals("toString()Ljava/lang/String;")) {
                    return CGLIB$toString$3$Proxy;
                }
                break;
            case 1984935277:
                if (var10000.equals("hashCode()I")) {
                    return CGLIB$hashCode$4$Proxy;
                }
        }

        return null;
    }

    /**
     * 无参构造方法,与委托基类一致
     */
    public DelegateClass$$EnhancerByCGLIB$$147414ed() {
        CGLIB$BIND_CALLBACKS(this);
        this.CGLIB$CONSTRUCTED = true;
    }

    /**
     * 有参构造方法,与委托基类一致
     */
    public DelegateClass$$EnhancerByCGLIB$$147414ed(String var1) {
        super(var1);
        CGLIB$BIND_CALLBACKS(this);
        this.CGLIB$CONSTRUCTED = true;
    }

    /**
     * 为代理子类实例绑定Callback
     */
    private static final void CGLIB$BIND_CALLBACKS(Object proxyInstance) {
        DelegateClass$$EnhancerByCGLIB$$147414ed proxyInst = (DelegateClass$$EnhancerByCGLIB$$147414ed) proxyInstance;
        if (!proxyInst.CGLIB$BOUND) {
            proxyInst.CGLIB$BOUND = true;
            Object callbacks = CGLIB$THREAD_CALLBACKS.get();
            if (callbacks == null) {
                callbacks = CGLIB$STATIC_CALLBACKS;
                if (CGLIB$STATIC_CALLBACKS == null) {
                    return;
                }
            }
            Callback[] callbackArray = (Callback[]) callbacks;
            proxyInst.CGLIB$CALLBACK_2 = (NoOp) ((Callback[]) callbacks)[2];
            proxyInst.CGLIB$CALLBACK_1 = (MethodInterceptor) callbackArray[1];
            proxyInst.CGLIB$CALLBACK_0 = (MethodInterceptor) callbackArray[0];
        }
    }

    /**
     * 设置代理类的Callback
     */
    public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] var0) {
        CGLIB$STATIC_CALLBACKS = var0;
    }

    /**
     * 设置代理子类实例的Callback
     */
    public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {
        CGLIB$THREAD_CALLBACKS.set(var0);
    }

    /**
     * 实现Factory接口方法
     * 创建代理子类实例,并设置实例的Callback
     */
    @Override
    public Object newInstance(Callback[] callbacks) {
        CGLIB$SET_THREAD_CALLBACKS(callbacks);
        DelegateClass$$EnhancerByCGLIB$$147414ed proxyInstance = new DelegateClass$$EnhancerByCGLIB$$147414ed();
        CGLIB$SET_THREAD_CALLBACKS((Callback[]) null);
        return proxyInstance;
    }

    /**
     * 实现Factory接口方法
     * 创建代理子类实例,并设置实例的Callback
     */
    @Override
    public Object newInstance(Callback callback) {
        throw new IllegalStateException("More than one callback object required");
    }

    /**
     * 实现Factory接口方法
     * 通过构造方法创建代理子类实例,并设置实例的Callback
     * @param constructorParameterTypes 构造方法参数类型
     * @param constructorParameterValues 构造方法参数对象
     */
    @Override
    public Object newInstance(Class[] constructorParameterTypes, Object[] constructorParameterValues, Callback[] callbacks) {
        CGLIB$SET_THREAD_CALLBACKS(callbacks);
        DelegateClass$$EnhancerByCGLIB$$147414ed var10000 = new DelegateClass$$EnhancerByCGLIB$$147414ed;
        switch (constructorParameterTypes.length) {
            case 0:
                var10000. ();
                break;
            case 1:
                if (constructorParameterTypes[0].getName().equals("java.lang.String")) {
                    var10000. ((String) constructorParameterValues[0]);
                    break;
                }

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

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

    /**
     * 实现Factory接口方法
     * 通过回调索引获取代理子类实例的Callback
     */
    @Override
    public Callback getCallback(int callbackIndex) {
        CGLIB$BIND_CALLBACKS(this);
        Object callback;
        switch (callbackIndex) {
            case 0:
                callback = this.CGLIB$CALLBACK_0;
                break;
            case 1:
                callback = this.CGLIB$CALLBACK_1;
                break;
            case 2:
                callback = this.CGLIB$CALLBACK_2;
                break;
            default:
                callback = null;
        }

        return (Callback) callback;
    }

    /**
     * 实现Factory接口方法
     * 通过回调索引设置代理子类实例的Callback
     */
    @Override
    public void setCallback(int callbackIndex, Callback callback) {
        switch (callbackIndex) {
            case 0:
                this.CGLIB$CALLBACK_0 = (MethodInterceptor) callback;
                break;
            case 1:
                this.CGLIB$CALLBACK_1 = (MethodInterceptor) callback;
                break;
            case 2:
                this.CGLIB$CALLBACK_2 = (NoOp) callback;
        }

    }

    /**
     * 实现Factory接口方法
     * 获取代理子类实例的所有Callback
     */
    @Override
    public Callback[] getCallbacks() {
        CGLIB$BIND_CALLBACKS(this);
        return new Callback[]{this.CGLIB$CALLBACK_0, this.CGLIB$CALLBACK_1, this.CGLIB$CALLBACK_2};
    }

    /**
     * 实现Factory接口方法
     * 设置代理子类实例的所有Callback
     */
    @Override
    public void setCallbacks(Callback[] callbacks) {
        this.CGLIB$CALLBACK_0 = (MethodInterceptor) callbacks[0];
        this.CGLIB$CALLBACK_1 = (MethodInterceptor) callbacks[1];
        this.CGLIB$CALLBACK_2 = (NoOp) callbacks[2];
    }

}

代理子类的核心是MethodProxy。代理子类为每个被拦截的方法创建了一个MethodProxy实例(如下),并通过该MethodProxy实例调用原始方法。

MethodProxy CGLIB$add$0$Proxy = MethodProxy.create(
    superClass, proxyClass, "(Ljava/lang/String;I)Z", "add", "CGLIB$add$0");

7. MethodProxy

MethodProxy的核心是为委托基类和代理子类生成FastClass(替代Java反射来调用方法,参见CGLib FastClass),利用FastClass来调用委托基类中的方法和代理子类中的副本方法。

public class MethodProxy {

    /**
     * 为要拦截的方法创建MethodProxy
     *
     * @param superClass       代理类继承的基类(方法所在类)
     * @param proxyClass       代理类
     * @param methodDescriptor 方法描述符(参数类型+返回类型)
     *                         委托基类方法和代理副本方法具有相同的方法描述符
     * @param superMethodName  基类方法
     * @param proxyMethodName  代理子类中的基类方法副本(使用super调用基类方法)
     */
    public static MethodProxy create(Class superClass, Class proxyClass, String methodDescriptor, String superMethodName, String proxyMethodName) {
        MethodProxy proxy = new MethodProxy();
        proxy.superMethodSignature = new Signature(superMethodName, methodDescriptor);
        proxy.proxyMethodSignature = new Signature(proxyMethodName, methodDescriptor);
        proxy.createInfo = new MethodProxy.CreateInfo(superClass, proxyClass);
        return proxy;
    }

    /** 委托基类方法签名 */
    private Signature superMethodSignature;

    /** 代理副本方法签名 */
    private Signature proxyMethodSignature;

    /** 动态创建FastClass要用到的信息 */
    private CreateInfo createInfo;
    
    /** 委托基类和代理子类的FastClass */
    private volatile MethodProxy.FastClassInfo fastClassInfo;

    private static class CreateInfo {
        // 基类
        Class superClass;
        // 代理类
        Class proxyClass;
        // 动态类命名策略
        NamingPolicy namingPolicy;
        // 动态类生成策略
        GeneratorStrategy strategy;
        boolean attemptLoad;

        public CreateInfo(Class superClass, Class proxyClass) {
            this.superClass = superClass;
            this.proxyClass = proxyClass;
            AbstractClassGenerator fromEnhancer = AbstractClassGenerator.getCurrent();
            if (fromEnhancer != null) {
                namingPolicy = fromEnhancer.getNamingPolicy();
                strategy = fromEnhancer.getStrategy();
                attemptLoad = fromEnhancer.getAttemptLoad();
            }
        }
    }

    private static class FastClassInfo {
        // 基类的FastClass
        FastClass superFastClass;
        // 代理类的FastClass
        FastClass proxyFastClass;
        // 基类FastClass中基类方法的索引
        int superMethodIndex;
        // 代理类FastClass中副本方法的索引
        int proxyMethodIndex;
    }

    private final Object initLock = new Object();
    
    /**
     * 初始化:为基类和代理类创建FastClass,并获取方法在基类和代理类中的索引
     */
    private void init() {
        if (fastClassInfo == null) {
            synchronized (initLock) {
                if (fastClassInfo == null) {
                    MethodProxy.CreateInfo ci = createInfo;
                    MethodProxy.FastClassInfo fci = new MethodProxy.FastClassInfo();
                    // 创建委托基类的FastClass
                    fci.superFastClass = helper(ci, ci.superClass);
                    // 创建代理子类的FastClass
                    fci.proxyFastClass = helper(ci, ci.proxyClass);
                    // 基类FastClass中基类方法的索引
                    fci.superMethodIndex = fci.superFastClass.getIndex(superMethodSignature);
                    // 代理类FastClass中副本方法的索引
                    fci.proxyMethodIndex = fci.proxyFastClass.getIndex(proxyMethodSignature);
                    this.fastClassInfo = fci;
                    createInfo = null;
                }
            }
        }
    }

    /**
     * 为基类或代理类创建FastClass
     * @param type 委托基类或代理子类
     */
    private static FastClass helper(MethodProxy.CreateInfo ci, Class type) {
        FastClass.Generator g = new FastClass.Generator();
        g.setType(type);
        g.setClassLoader(ci.proxyClass.getClassLoader());
        g.setNamingPolicy(ci.namingPolicy);
        g.setStrategy(ci.strategy);
        g.setAttemptLoad(ci.attemptLoad);
        return g.create();
    }

    /**
     * 调用代理子类中的基类方法副本
     *
     * @param proxyInstance   代理子类实例,
     *                        必须是传给MethodInterceptor.intercept方法的第一个参数对象
     * @param parameterValues 方法参数对象,
     *                        可以是传给MethodInterceptor.intercept方法的第三个参数对象,
     *                        也可以使用类型兼容的其他对象数组
     */
    public Object invokeSuper(Object proxyInstance, Object[] parameterValues) throws Throwable {
        try {
            init();
            MethodProxy.FastClassInfo fci = fastClassInfo;
            // 使用代理子类的FastClass和代理副本方法索引调用代理副本方法
            // 代理副本方法通过super调用基类方法
            // 传入代理子类实例和方法参数对象
            return fci.proxyFastClass.invoke(fci.proxyMethodIndex, proxyInstance, parameterValues);
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        }
    }

    /**
     * 调用基类中的原始方法
     *
     * @param superInstance   委托基类实例,
     *                        如果传入MethodInterceptor.intercept方法的第一个参数对象会导致循环调用
     * @param parameterValues 方法参数对象,
     *                        可以是传给MethodInterceptor.intercept方法的第三个参数对象,
     *                        也可以使用类型兼容的其他对象数组
     */
    public Object invoke(Object superInstance, Object[] parameterValues) throws Throwable {
        try {
            init();
            MethodProxy.FastClassInfo fci = fastClassInfo;
            // 使用委托基类的FastClass和基类方法索引调用基类方法
            // 传入委托基类实例和方法参数对象
            return fci.superFastClass.invoke(fci.superMethodIndex, superInstance, parameterValues);
        } catch (InvocationTargetException e) {
            throw e.getTargetException();
        } catch (IllegalArgumentException e) {
            if (fastClassInfo.superMethodIndex < 0)
                throw new IllegalArgumentException("Protected method: " + superMethodSignature);
            throw e;
        }
    }
    
    /**
     * 找到代理子类中匹配方法签名的MethodProxy
     *
     * @param proxyClass 代理子类
     * @param sig        方法签名
     * @return MethodProxy实例
     */
    public static MethodProxy find(Class proxyClass, Signature sig) {
        try {
            // 调用代理子类的CGLIB$findMethodProxy方法
            // 找到方法签名对应的MethodProxy实例
            Method m = proxyClass.getDeclaredMethod(MethodInterceptorGenerator.FIND_PROXY_NAME,
                    MethodInterceptorGenerator.FIND_PROXY_TYPES);
            return (MethodProxy) m.invoke(null, new Object[]{sig});
        } catch (NoSuchMethodException e) {
            throw new IllegalArgumentException("Class " + proxyClass + " does not use a MethodInterceptor");
        } catch (IllegalAccessException e) {
            throw new CodeGenerationException(e);
        } catch (InvocationTargetException e) {
            throw new CodeGenerationException(e);
        }
    }
    
}

你可能感兴趣的:(CGLib)