cglib的原理是生成一个被代理类的子类进行增强, 那么为什么子类访问不到父类的属性呢
@Service
public class AopTestService {
public String value = "hello world";
@Transactional
public void imTest() {
Object obj = SpringUtil.getBean(this.getClass());
boolean bool1 = AopUtils.isAopProxy(obj);
boolean bool2 = AopUtils.isAopProxy(this);
System.err.println(StrUtil.format("bool1:{}, bool2:{}, value:{}", bool1, bool2, this.value));
}
@Transactional
public final void noImTest() {
Object obj = SpringUtil.getBean(this.getClass());
boolean bool1 = AopUtils.isAopProxy(obj);
boolean bool2 = AopUtils.isAopProxy(this);
System.err.println(StrUtil.format("bool1:{}, bool2:{}, value:{}", bool1, bool2, this.value));
System.err.println(this.getValue());
}
public String getValue() {
return value;
}
}
@Autowired
AopTestService aopTestService;
@PostConstruct
public void test() {
aopTestService.imTest();
aopTestService.noImTest();
System.err.println("test: " + aopTestService.value);
}
输出
bool1:true, bool2:false, value:hello world
bool1:true, bool2:true, value:null
hello world
test: null
-
第一行: bool1肯定为true, 因为这是从容器中取到的对象. 根据aop代理规则,
imTest
方法可以被代理, 下面就是cglib生成的子类方法, 通过var10000.intercept
代理拦截器, 最终使用源类AopTestService
的对象去调用imTest
方法public final void imTest() { MethodInterceptor var10000 = this.CGLIB$CALLBACK_0; if (var10000 == null) { CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_0; } if (var10000 != null) { var10000.intercept(this, CGLIB$imTest$2$Method, CGLIB$emptyArgs, CGLIB$imTest$2$Proxy); } else { super.imTest(); } }
所以,
bool2
为false
,this.value
正常输出 -
第二行:
bool2
为true
, 因为noImTest
方法被final
修饰, 无法被代理增强, 所以最终是通过cglib生成的子类去调用父类AopTestService
的noImTest
方法. 但是this.value
输出null
, 这是因为cglib生成的子类对象, 是通过objenesis
这个库实例化的,objenesis
这个库的作用是绕过构造方法实例化对象. 所以对象没有正常的初始化, 父类的value
属性也就没有了 -
第三行,
this.getValue
输出了. 这个方法也是被子类重写了, 最终也是通过源类AopTestService
的对象去调用对应方法, 所以能够输出public final String getValue() { MethodInterceptor var10000 = this.CGLIB$CALLBACK_0; if (var10000 == null) { CGLIB$BIND_CALLBACKS(this); var10000 = this.CGLIB$CALLBACK_0; } return var10000 != null ? (String)var10000.intercept(this, CGLIB$getValue$0$Method, CGLIB$emptyArgs, CGLIB$getValue$0$Proxy) : super.getValue(); }
-
第四行: 原因同第二行
注意: 本文归作者所有, 未经作者允许, 不得转载. 若有谬误, 欢迎指出