Spring AOP 剖析(3)
AOP? 涉及到的几个基本概念
?
1. Joinpoint????????????????? --- ? ? 可以在系统中织入横切逻辑的位置 ??
2. Pointcut?????????????????? ---???? 用来描述系统中所有需要织入横切逻辑的 Joinpoint 的集合
3. Advice????????????????????? ---???? 将要被织入到 Joinpoint 中的横切逻辑
4. Aspect ? ? ? ? ? ? ? ? ? ?? --- ? ? 对 以上三种概念 进行模块化的封装,相当于 OOP 中的 Class
5. Weaving And Weaver ? --- ? 具体完成横切逻辑到系统的最终织入,这个相当重要啊,没有这个,其他的都是扯淡了
6. Target Object ? ? ? ? ?? --- ? 满足 Pointcut 的条件,将要被织入横切逻辑的对象
?
?
1. Jointpoint
?
系统运行之前,AOP 的功能模块都需要织入到 OOP 的功能模块中。要进行这种织入过程,就需要知道在系统的哪些
?
执行点上进行织入操作,这些将要在其上进行织入操作的系统执行点就是 Joinpoint。
?
?
常见的 Joinpoint 类型:
?
a.? Method Call? (方法调用) -- 当某个方法被调用的时候所处的程序执行点。
b.? Method Call Execution (方法执行) -- 某个方法内部执行开始时点。
?
Method Call 是在调用对象上的执行点,而 Method Call Execution 则是在被调用到的方法逻辑执行的时点,对于同一对象,方法调用要先于方法执行。
?
如图:
?

?
c.? Constructor Call (构造方法调用) -- 程序执行过程中对某个对象调用其构造方法进行初始化的时点。
?
d.? Constructor Call Execution (构造方法执行) -- 构造方法执行和构造方法调用之间的关系类似于方法执行和方法调用之间的关系,指的是某个对象构造方法内部执行的开始时点。
?
e.? Field Set (字段设置) -- 对象的某个属性通过 setter 方法被设置或者直接被设置的时点。 该 Joinpoint 的本质是对象的属性被设置,而通过 setter 方法设置还是直接设置触发的时点是相同的。
?
f. ? Exception Handler Execution (异常处理执行) -- 该类型的 Joinpoint 对应程序执行过程中,在某些类型异常抛出后,对应的异常处理逻辑执行的时点。
?
g.? Class Initialization (类初始化) -- 该 Joinpoint 指的是类中某些静态类型或者静态块的初始化时点。
?
?
?
2.? Pointcut
?
Joinpoint 只是指明: 可以在系统中织入横切逻辑的一些时点而已。 所以光有 Joinpoint 是远远不够的。?
?
接下来需要知道, 我需要织入横切逻辑的所有的具体位置到底是在哪里呢,即到底在哪些 Joinpoint 上面呢?
?
那么,Pointcut 就是做这个工作的, 她用来说明系统中所有需要织入横切逻辑的位置具体是哪些 Joinpoint。
?
?
关于 Pointcut 是如何描述 系统中所有需要织入的横切逻辑的具体 Joinpoint? 的呢?
?
a.? 直接指定 Joinpoint 所在的方法名称。
?
????? 这种形式的 Pointcut 表述方式比较简单,而且功能单一,通常只限于支持方法级别的 Joinpoint 的 AOP 框架,或者
?
只是方法执行类型的 Joinpoint。 而且,即使是只针对方法级别的 Joinpoint, 因为系统中需要织入横切逻辑的方法可能
?
很多,一个一个地指定则过于不便,所以这种方式通常只限于 Joinpoint 较少且较为简单的情况。
b.? 正则表达式。
?
????? 这是比较普遍的 Pointcut 表达方式,可以充分利用正则表达式的强大功能,来归纳表述需要符合某种条件的多组
?
Joinpoint。 几乎现在大部分的 Java 平台的 AOP 产品都支持这种形式的 Pointcut 表达形式。 Spring 的 AOP 框架就
可以采用正则表达式的方式来描述 Pointcut 。
?
c.? 使用特定的 Pointcut 表述语言。
?
????? 这是一种最为强大的表达 Pointcut 的方式,灵活性也很好,但具体实现起来可能过于复杂,需要设置该表述语言的
?
语法,实现相应的解释器等许多工作。 AspectJ 使用这种方式来指定 Pointcut,它提供了一种类似于正则表达式的针对
?
Pointcut 的表述语言,在表达 Pointcut 方面支持比较完善。 Spring 从2.0版之后,借助 AspectJ 的 Pointcut
表述语言解释器,现在也支持使用 AspectJ 的 Pointcut 表述语言来指定 Pointcut 。
?
?
?
?
3.? Advice
?
OK,现在有了? 可以植入横切逻辑的时点(Joinpoint), 也有了 需要织入横切逻辑的所有的时点的集合(Pointcut),
?
但是,还不知道需要织入的 横切逻辑 到底是什么呢? 于是乎 Advice 就出现了。
?
Advice 代表将会被织入到 Joinpoint 的横切逻辑。
?
?
按照 Advice 在 Joinpoint 位置执行时机的差异或者完成功能的不同,Advice可以分为多种具体形式。
?
a.? Before Advice
?
Before Advice 是在 Joinpoint 指定位置之前执行的 Advice 类型。通常,它不会中断程序执行流程,但如果必要,
?
可以通过在 Before Advice 中抛出异常的方式来中断当前流程。 如果当前 Before Advice 将被织入到方法执行类型的
?
Joinpoint, 那么这个 Before Advice 就会先于方法执行而执行。
?
b.? After Advice
?
After Advice 是在 Joinpoint 指定位置之后执行的 Advice 类型,但是该类型的 Advice 还可以细分为以下三种:
1.? After returning Advice?? 只有当 Joinpoint 处执行流程正常完成后,After returning Advice 才会执行。
?
比如:方法执行正常返回而没有抛出异常。
?
2.? After throwing Advice??? 又称为? Throws Advice , 只有在当前 Joinpoint 执行过程中抛出异常的情况下,才会
?
执行。 比如:方法执行类型的 Joinpoint 抛出某异常而没有正常返回。
?
3.? After Advice? 或许叫 After (Finally) Advice 更为准确, 该类型 Advice 不管 Joinpoint 处执行流程是正常
?
还是抛出异常都会执行, 就好像 Java 中的 finally 块一样。
?

c.? Around Advice?
?
Around Advice 是对附加其上的 Joinpoint 进行“包裹”, 可以在 Joinpoint 之前和之后都指定相应的逻辑,甚至于中断
?
或者忽略 Joinpoint 处原来程序流程的执行。
?
好吧,找不到图了,自己画一个, 大概就这样子吧。
?

既然 Around Advice 可以在 Joinpoint 之前和之后都能执行相应的逻辑,那么,它自然可以完成 Before Advice 和
?
After Advice 的功能。 不过,通常情况下,还是应该根据场景选用更为具体的 Advice 类型。
?
Around Advice 应用场景非常广泛,J2EE 中 Filter 功能就是一种 Around Advice 。 使用它,我们可以完成
?
“资源初始化”,“安全检查”之类的 系统横切关注点了。
?
d.? Introduction?
?
Introduction 不是根据横切逻辑在 Joinpoint 处的执行时机来区分的,而是根据它可以完成的功能而区别于
?
其他 Advice 类型。? Introduction 可以为原有的对象添加新的特性或者行为。
?
关于这种 Advice , 我还不是很了解, 就先放下,以后弄明白再补充。 O(∩_∩)O~
?
?
4.? Aspect
?
Aspect 是对系统中的横切关注点逻辑进行模块化封装的 AOP 概念实体。 通常,Aspect 可以包含多个 Pointcut 以及
?
相关的 Advice 定义。 比如,以 AspectJ 形式定义的 Aspect :
?

? Spring AOP 最初没有 “完全” 确切的实体对应真正的 Aspect 的概念。 在 2.0 发布后, 因为集成了 AspectJ ,所以
?
可以通过使用 @AspectJ 的注解并结合普通的 POJO 来声明 Aspect 。
?
?
?
5.? Weaving And Weaver
?
Weaving(织入)过程就是连接 AOP 与 OOP 的那座桥, 只有经过织入过程后,以 Aspect 模块化的横切逻辑才会集成
?
到 OOP 的现存系统中。而完成织入过程的那个 “人”? 就称为 Weaver (织入器)。
?
?
AspectJ 有 专门的编译器 来完成织入操作, 即 ajc ,所以 ajc 就是 AspectJ 完成织入的 织入器;
?
JBoss AOP 采用 自定义的类加载器 来完成最终织入,那么这个 自定义的类加载器 就是它的织入器;
Spring AOP 使用 一组类 来完成最终的织入操作, ProxyFactory类 则是 Spring AOP 最通用的织入器;
?
总之, Java平台 AOP 实现的织入器形式各样,唯一形同的就是它们的职责,即 完成横切关注点逻辑到系统的最终织入。
?
?
?
6.? Target Object
?
符合 Pointcut 所指定的条件,将在织入过程中被织入横切逻辑的对象,称为 Target Object (目标对象)
?
?
?
AOP 各种概念组合图
?
