惊人!Spring5 AOP 默认使用Cglib ?从现象到源码深度分析
Spring5 AOP 默认使用 Cglib 了?我第一次听到这个说法是在一个微信群里:
真的假的?查阅文档
刚看到这个说法的时候,我是保持怀疑态度的。
大家都知道 Spring5 之前的版本 AOP 在默认情况下是使用 JDK 动态代理的,那是不是 Spring5 版本真的做了修改呢?于是我打开 Spring Framework 5.x 文档,再次确认了一下:
文档地址:upload/201910301149565488.png" alt="Spring Framework 5.x 文档" style="margin: 0px; padding: 0px; border: none; max-width: 800px; height: auto;" />
简单翻译一下。Spring AOP 默认使用 JDK 动态代理,如果对象没有实现接口,则使用 CGLIB 代理。当然,也可以强制使用 CGLIB 代理。
什么?文档写错了?!
当我把官方文档发到群里之后,又收到了这位同学的回复:
SpringBoot 2.x 代码示例
为了证明文档写错了,这位同学还写了一个 DEMO。下面,就由我来重现一下这个 DEMO 程序:
运行环境:SpringBoot 2.2.0.RELEASE 版本,内置 Spring Framework 版本为 5.2.0.RELEASE 版本。同时添加 spring-boot-starter-aop 依赖,自动装配 Spring AOP。
public interface UserService { void work(); } @Service public class UserServiceImpl implements UserService { @Override public void work() { System.out.println("开始干活...coding..."); } }
@Component @Aspect public class UserServiceAspect { @Before("execution(* com.me.aop.UserService.work(..))") public void logBefore(JoinPoint joinPoint) { System.out.println("UserServiceAspect.....()"); } }
UserServiceImpl
实现了UserService
接口,同时使用UserServiceAspect
对UserService#work
方法进行前置增强拦截。从运行结果来看,这里的确使用了 CGLIB 代理而不是 JDK 动态代理。
难道真的是文档写错了?!
@EnableAspectJAutoProxy 源码注释
在 Spring Framework 中,是使用
@EnableAspectJAutoProxy
注解来开启 Spring AOP 相关功能的。Spring Framework 5.2.0.RELEASE 版本
@EnableAspectJAutoProxy
注解源码如下:
通过源码注释我们可以了解到:在 Spring Framework 5.2.0.RELEASE 版本中,
proxyTargetClass
的默认取值依旧是false
,默认还是使用 JDK 动态代理。难道文档和源码注释都写错了?!
@EnableAspectJAutoProxy 的 proxyTargetClass 无效了?