AOP的几大关键部分:
1. PointCut
即在哪个地方进行切入,它可以指定某一个点,也可以指定多个点。
比如类A的methord函数,当然一般的AOP
与语言(AOL)会采用多用方式来定义PointCut
,比如说利用正则表达式,可以同时指定多个类的多个函数。
2. Advice
在切入点干什么,指定在PointCut
地方做什么事情(增强),打日志、执行缓存、处理异常等等。
3. Advisor/Aspect
PointCut + Advice
形成了切面Aspect
,这个概念本身即代表切面的所有元素。但到这一地步并不是完整的,因为还不知道如何将切面植入到代码中,解决此问题的技术就是PROXY
。
4. Proxy
Proxy
即代理,其不能算做AOP
的家庭成员,更相当于一个管理部门,它管理 了AOP的如何融入OOP。之所以将其放在这里,是因为Aspect
虽然是面向切面核心思想的重要组成部分,但其思想的践行者却是Proxy
,也是实现AOP的难点与核心据在。
Spring AOP中各部分的实现
1. PointCut
参考下面的手工类图,以PointCut
为核心展开,只列举了几个关键类。
PointCut
依赖了ClassFilter
和MethodMatcher
,ClassFilter
用来指定特定的类,MethodMatcher
指定特定的函数,正是由于PointCut
仅有的两个依赖,它只能实现函数级别的AOP。
MethodMatcher
有两个实现类StaticMethodMatcher
和DynamicMethodMatcher
,它们两个实现的唯一区别是isRuntime
。StaticMethodMatcher
不在运行时检测,DynamicMethodMatcher
要在运行时实时检测参数,这也会导致DynamicMethodMatcher
的性能相对较差。
类似继承于StaticMethodMatcher
和DynamicMethodMatcher
也有两个分支StaticMethodMatcherPointcut
和DynamicMethodMatcherPointcut
,StaticMethodMatcherPointcut
是我们最常用,其具体实现有两个:
-
NameMatchMethodPointcut
: 通过name
进行匹配。 -
JdkRegexpMethodPointcut
:通过正则表达式匹配。
其他PointCut
: -
ExpressionPointcut
,它的出现是了对AspectJ
的支持,所以其具体实现也有AspectJExpressionPointcut
另外还有三个更强功能的PointCut
: -
AnnotationMatchingPointcut
:可以指定某种类型的注解 -
ComposiblePointcut
:进行与或操作 -
ControlFlowPointcut
:这个有些特殊,它是一种控制流,例如类A 调用B.method(),它可以指定当被A调用时才进行拦截。
2. Advice
参考如下手工类图,不完整,但是可以代表基本的类和接口关系。
-
AfterAdvice
是指函数调用结束之后增强,它又包括两种情况:
-- 异常退出ThrowsAdvice
-- 正常退出AfterReturningAdvice
-
BeforeAdvice
指函数调用之前增强; -
Inteceptor
有点特殊,它是由AOP联盟定义的标准,也是为了方便Spring AOP
扩展,以便对其它AOL支持。每个Interceptor
里都包含一个对应Advice
的实例。
3. Advisor/Aspect
参考上面第一个图。我们主要研究PointCutAdvisor
。
首先对每个不同类型的PointCut
,对应一个相应类型的PointCutAdvisor
。
而每个Advisor
中包含两个部分,PointCut
和Advice
。
AbstractPointcutAdvisor
实现了Ordered
,为多个Advice
指定顺序,顺序为Int类型,越小优先级越高。