相关链接:Spring AOP 扫盲(应用篇)
Spring AOP 简介
AOP 是 Aspect-oriented programming 的简称,意为面向切面编程。它可以将跨越多个业务模块的相似特性,单独抽取出来,形成独立的模块,与业务模块更好地解藕,常见的使用场景有日志、事务管理、性能监控等。
Spring AOP 是 Spring 框架对 AOP 特性的支持。Spring 框架最为人熟知的两大特性就是 IOC 和 AOP,其中 IOC 特性是通过 Spring 容器来实现的,它也是 Spring 框架的「地基」。
Spring 的 AOP 特性也是在 IOC 的基础上实现的,而且,Spring AOP 并不致力于提供完备的面相切面编程的功能,而是让 Spring 的 IOC 特性能更好地服务于应用开发。因此,我觉得 AOP 并不算是与 IOC 并列的 Spring 特性,而是 IOC 容器特性的增强。
以下是 Spring 框架的架构图,也可以看到 AOP 其实是基于核心容器的更上层的特性。
Spring AOP 相关概念
下面对 Spring AOP 特性中涉及到的关键概念做一个简单的解释。
Aspect
通常被翻译为切面,虽然把英文翻译成了中文,但对于不了解 AOP 的初学者来说,依然是一个无法理解的概念,相当于没翻译。它指的是,使用一个独立的增强模块,对其他多个独立的不同业务模块进行增强的过程,也就是 AOP 发生作用的过程。
举个例子,比如我们有个包含多个独立业务模块的系统,现在需要对所有业务模块增加性能监控的特性,如果不使用 AOP 特性,就需要在每个业务模块中增加性能监控的逻辑,而通过 AOP 特性,可以单独开发一个性能监控的增强模块,然后使用这个增强模块对所有的业务模块进行增强,这个过程就叫做 Aspect。
再举一个形象但是不一定恰当的类比,比如你正在吃一个汉堡,你觉得汉堡里的肉太少了,你想让你吃的每一口汉堡中肉能再多一点,你并不需要每吃一口汉堡是再另外吃一块肉,而是往汉堡里再多加一个肉饼,这样,你之后吃的每一口汉堡中的肉都增加了。这个往汉堡里额外夹一块肉饼的过程,就叫 Aspect。希望我讲明白了。
在 Spring AOP 中,被增强的通常是一个方法。
Join point
通常叫做连接点,在 Spring AOP 中,一个方法的执行就是一个 Join point。也可以说,一个 Join point 就是一个可以被增强的对象,比如一个汉堡。
Point cut
也叫切入点,根据 Spring 官方文档中的解释,Point cut 是用来匹配 Join point 的谓词。也就是说,它可以用来匹配要被增强的连接点。在 Spring 中,一个切入点通常是用一个表达式来表示的,Spring 默认使用的是 AspectJ 的切入点表达式语言。(顺便介绍一下,AspectJ 是一个独立的 AOP 框架)
举个例子:execution(* com.xyz.service.AccountService.*(..))
就是一个 AspectJ 的切入点表达式,它可以用来匹配定义在com.xyz.service.AccountService
类中的所有方法。
Advice
前面我们一直在提一个词「增强」,Advice 就是增强本强,上面几个概念的介绍中,我们知道了,切面就是对切入点匹配到的连接点进行增强的过程,那什么是增强呢?比如我们要使用 AOP 的方式,给所有的业务请求增加性能监控的模块,那么这个性能监控的功能就叫做增强,也就是给目标连接点额外增加的执行逻辑,也就是汉堡例子中,额外增加的那一个肉饼。
在 Spring AOP 中,Advice 分几种类型。
- Before(前置增强):在目标方法执行前执行
- After(后置增强):在目标方法执行后执行(无论是否有异常抛出)
- AfterThrowing(异常抛出增强):在目标方法抛出异常时执行
- AfterReturning(返回后增强):在目标方法执行后执行(没有异常抛出)
- Around(环绕增强):在目标方法执行前后分别执行增强逻辑,甚至可以决定是否执行切入点方法。
这些增强逻辑的执行顺序是这样的:
- 当目标方法正常执行完(不抛出异常)的情况下:环绕增强的前段逻辑 -> 前置增强 -> 目标方法逻辑 -> 返回后增强 -> 后置增强 -> 环绕增强的后段逻辑
- 当目标方法抛出异常的情况下:环绕增强的前段逻辑 -> 前置增强 -> 目标方法逻辑 -> 异常抛出增强 -> 后置增强
知道了以上这几个概念,就能理解 AOP 的基本逻辑了。
Spring 实现 AOP 的方式
Spring 实现 AOP 特性的方式是通过 JDK 动态代理或者 cglib 动态代理,在代理方法中添加增强的逻辑。作为一个纯 Java 当 AOP 框架,Spring 对目标方法的增强,都是在运行时完成的。
总结
本文介绍了一些 Spring AOP 相关的基础概念和原理,适合初学者阅读。