Spring AOP的术语汇总

653 阅读5分钟

前言

本来我觉得这部分东西是没什么好说的,结果上周面试被问到了,东扯西扯半天,只说了个大概,这部分本来可以说的更好的,所以写个文章来总结下,说不定有机会还用得上

首先声明一点,本文讲的是Spring AOP中的术语,是AOP框架的定义,所以不要将AOP与动态代理混为一谈,AOP是一种思想,而动态代理是一种解决方案

为了下文能更形象地描述,这里预设一个AOP的场景:老师上课前需要黑板是干净的,也就是说需要有人来帮忙擦黑板

术语

这里将术语分为两类,一类是对象术语,另一类是行为术语。对象术语指的是用于描述AOP中的各个对象部分,而行为术语指的是在AOP实现过程中涉及到的具体行为

对象术语

通知(Advice)

通知指的是AOP在正常流程之外额外要执行的动作,也就是通过AOP为目标方法[1]新增的内容。根据前言中预设的场景,擦黑板这一行为就被叫做通知

确切地来说,通知描述了在正常流程之外额外要执行的具体工作,以及何时执行这个工作。根据通知执行时间的不同,Spring AOP中可以应用以下五种类型的通知

  • 前置通知(Before):在目标方法被调用前执行的行为
  • 后置通知(After):在目标方法执行完成后执行的行为,不能获取到方法的输出
  • 返回通知(After-returning):在目标方法成功执行后执行的行为,可以获取到方法的输出
  • 异常通知(After-throwing):在目标方法抛出异常后执行的行为
  • 环绕通知(Around):包裹了目标方法,可以在其执行前后执行自定义的行为

连接点(Join point)

连接点指的是应用通知的时机,比如老师上课前这一时间点就是连接点。代码可以利用这些点插入原本的正常方法流程中,以添加新的行为

可能有人会有疑问,不是刚刚说通知也表示了执行的时机,那连接点的定义不是重复了吗?

通知描述了在正常流程之外额外要执行的具体工作,以及何时执行这个工作

我个人理解是这样的,这两个地方并不冲突。就比方说我们告诉别人“我吃早饭”,但是他们只知道我们吃的是早饭,重点是饭,而连接点则是将“早”这个概念抽象出来,比如“我在早上吃早饭”,重点就在“早”而不是“饭”。也就说是,通知的重点是内容,而连接点的则是将通知的应用时机细分出来

切点(Pointcut)

对于我们在方法正常流程之外执行的额外操作而言,通知定义了这些操作执行的内容时机切点则是定义了这些操作执行的位置

对于我们预设的那个场景而言,不能只粗略说是在“老师”“上课”前擦黑板,而应该指明是什么老师,上什么课,比如我们可以说“所有一年级老师上政治课”前擦黑板,或是“所有姓刘的老师上数学课”前擦黑板

AOP会根据切点的定义,来匹配一个或多个连接点,然后应用我们的通知。我们通常会使用明确的类/方法名,或是正则表达式来指定切点。根据AOP框架的不同,切点匹配的自由度也会不同

切面(Aspect)

切面是切点通知的结合,定义了我们的功能在何时、何处、以及如何执行

切面定义了AOP的核心内容,在上述场景中,切面知道自己要做什么(擦黑板),在哪做(A老师上B课的教室),以及何时做(上课前)

行为术语

引入(Introduction)

引入指的向现有的类中添加新的方法或属性。我们可以将新的方法或属性引入到目标类中,这样目标类就具有了新的方法,同时还不用修改现有具体类的定义

织入(Weaving)

相比与引入,织入的概念更为重要。织入指的是将切面应用到目标对象,在这个过程中会生成新的代理对象

织入的执行的时机有以下几个[2]

  • 编译期:在目标类被编译时进行织入,需要依赖于特殊的编译器。AspectJ的织入编译器就采用的这种方式
  • 类加载期:在目标类被加载到JVM时进行织入,需要依赖于特殊的类加载器。这种方式会在目标类被引入应用前增强目标类的字节码
  • 运行期:在应用运行的某一具体时刻进行织入。在这种情况下,AOP容器会为目标对象动态地创建一个代理对象,Spring AOP就采用的这种方式

总结

以上这些就是AOP中的常用术语,这些术语虽然你可能根本用不到,但是一定要知道,能明白代码中的某个部分属于AOP的哪个部分,否则永远都会是一个不断写简单的业务代码的码农而已

最后总结一下对象术语,我们完整的场景如下:

王老师在上语文课前,需要有人来擦黑板

在这个场景中,各自对象代表的内容如下:

  • 被增强的方法:王老师的语文课
  • 目标方法所在类:王老师
  • 通知(前置通知):做某事前擦黑板,重点是擦黑板这一行为
  • 连接点:老师上课前的时间,并不确定是哪些老师上哪门课前
  • 切点:王老师上语文课前这一时间点
  • 切面:在王老师上语文课前擦黑板

  1. 目标方法指的是AOP所切入的方法,在上述场景中,老师上课这一行为就是目标方法 ↩︎

  2. 参考《Spring in Action》 ↩︎