Spring Aop Cglib Jdk问题
太乱不看版总结:
Spring 的 AOP都是用代理实现的 代理是无法拦截 内部调用
如果要拦截内部调用 就得编译时织入(修改字节码 修改目标对象)
SpringBoot2 默认就使用 Cglib 进行 AOP
可以在注入的Bean getClass().getName() 查看 名称肯定都带有 $$EnhancerBySpringCGLIB$$fda183c9
百度 SpringBoot AOP无法拦截类内部的调用方法 很多都甩锅JDK代理 说使用Cglib就没问题
现在默认就是 cglib 但使用时还是碰到内部类无法被拦截的问题
实测添加注解
@EnableAspectJAutoProxy(exposeProxy=true,proxyTargetClass=true)
无效
比如 https://blog.csdn.net/piaoslowly/article/details/81743692 讲的非常详细
https://blog.csdn.net/dm_vincent/article/details/57526325
关于动态代理和CGLIB这两种方式的简要总结如下:
- JDK动态代理(Dynamic Proxy)
- 基于标准JDK的动态代理功能
- 只针对实现了接口的业务对象
- CGLIB
- 通过动态地对目标对象进行子类化来实现AOP代理,上面截图中的
SampleBean$$EnhancerByCGLIB$$1767dd4b
即为动态创建的一个子类- 需要指定
@EnableAspectJAutoProxy(proxyTargetClass = true)
来强制使用- 当业务对象没有实现任何接口的时候默认会选择CGLIB
Spring 的 AOP 都是基于动态代理
所以是无法解决 内部接口调用
即使是CGLIB也是使用了动态代理
最大的区别在于两者实现AOP的底层原理不太一样:
- Spring AOP: 基于代理(Proxying)
- AspectJ: 基于字节码操作(Bytecode Manipulation)
如果非要动态调用内部的 就得使用 AspectJ
CGLIB 为什么也不能代理
这篇文章讲的很详细
https://blog.csdn.net/luanlouis/article/details/24589193
1 | package samples; |
CGLIB 生成出来的动态代理类 也不能拦截到你内部调用
因为他也只是继承目标类 并不是修改目标类
AspectJ 就像 Javassist 是编译时直接修改了目标类 而不是继承目标对象进行拦截