之前在 Spring AOP 应用篇,讲述了 AOP 的使用,这一篇来讲一些 Spring AOP的实现原理。
Spring 主要通过两种技术来实现 AOP,Java 动态代理 和 CGLib 动态代理
Java 动态代理
由于知识点比较多,单独写来一篇文章,参考 设计模式之动态代理
CGLib 动态代理
参考 CGLib 动态代理
Spring AOP 的选择策略
既然有两种技术可以实现,那么实际运用时,到底选择的是哪一种呢?
默认的选择策略是
- 如果目标类实现了接口,则选择 java动态代理技术
- 如果目标类没有实现了接口,则选择CGLib 动态代理,前提是目标类没有被 final 修饰。
多个 AOP 作用到同一个目标类时的执行顺序
实际应用中经常遇到这样的情况,那么这多个AOP的执行顺序是怎么样的呢,答案是链式调用
番外
Aspectj
在使用 Spring AOP 的过程中,我们经常用的 Aspectj的注解。比如 @Aspect、@Pointcut、@Before、@After等
哪个这个 Aspectj 是什么呢
Aspectj 也是一个 AOP 框架,与 Spring AOP不同的是,它不是通过动态代理实现的。而是在编译时,就把代理方法植入到目标方法中
- 由于是静态织入的,所以性能相对来说比较好
- 由于是静态织所以也不受类的限制,不管是private、或者static、或者final的,不管有没有接口都可以代理
- Aspectj不会代理除了限定方法之外任何其他诸如toString()等方法
Spring AOP 与 Aspectj 的关系
Spring AOP 虽然引用了Aspectj的一些核心概念,比如Aspect、advice、joinpoint等,也使用了AspectJ中的一些注解。比如@pointCut、@after、@before等。
但Spring AOP 并不是 Aspectj,它不会向 Aspectj一样,在编译时,就把代理方法植入到目标方法中。它只是用了一些 Aspectj的工具,并对java动态代理和CGLIB代理做了一层封装,所以实际上Spring AOP和Aspectj的关系并不大