1. 内部调用不被代理
Cglib生成的代理类继承被代理类,代理类实例持有 target 实例。
相当于 proxy 有个字段 target,然后我们持有 proxy,当调用 proxy.method,代理实例 proxy 当然知道我们调用了哪个方法,于是进行 taget.method 调用,当在 target.method 内调用 this.methodInternal 时,this 是谁?显然是 target ,要注意 proxy 和 target 是两个实例,在 proxy.method 内调用 this.methodInternal 和在 target.method 内调用 this.methodInternal 是不一样的,前者调用被 proxy 重写的(代理)methodInterenal,后者的运行时类型就是 target 类型而非 proxy 代理后类型,因此两者之间不存在多态
2. protected、public字段
当我们在 target 中声明 protected、public 的字段,那么在 proxy 中是可以访问的,但是得到的都是 null
之前我就有这种情况,使用 @Async 异步调用,为了方便测试,内部字段使用 public 访问,结果总是 NPE(即便你的字段使用 new Xxx 赋予默认值了)
这里的问题就是 Spring 创建 Cglib 动态代理实例的时候是如何创建的,如果是普通构造函数调用显然父类的字段会被初始化的(构造函数 OR 默认值 OR 初始化块)
org.springframework.aop.framework.ObjenesisCglibAopProxy#createProxyClassAndInstance 这里创建实例,向下还有几层使用策略模式调用的,略过,直接说最终的
SunReflectionFactoryInstantiator 进行实例化
public class SunReflectionFactoryInstantiator implements ObjectInstantiator {
private final Constructor mungedConstructor;
// 要实例化的 Class 类型, 动态代理实例化时是生成的代理类 Class
public SunReflectionFactoryInstantiator(Class type) {
// 这里获取 Object 类的构造函数, 不是代理类的
Constructor