- org.springframework.aop.BeforeAdvice : 普遍意义上的前置增强 (用与将来版本扩展定义)
- 一般切面。仅包含一个Advice,代表横切的连接点是所有目标类的所有方法
-
Spring AOP的工作目的
- 把相同重复的代码抽取出来,达到代码复用
-
原理
- AOP采用横向抽取的方式把诸如方法内的重复的并且与核心业务逻辑相关的代码提取出来,而这些重复代码却不能依靠传统的纵向抽取(继承)来实现。因为他们往往嵌于代码方法内部,难以通过继承来达到复用。
-
术语
-
连接点 Joinpoint
- Spring仅支持方法的连接点,即仅能在方法调用前、后、前后同时以及抛出异常时织入增强
-
增强 Advice
- 织入到目标类连接点上的一段代码
- Spring使用增强类定义了横切逻辑,同时由于Spring只支持方法连接点,所以增强在Spring中还包括了在方法的哪一点加入横切代码的方位信息
- (在其他语言的连接点概念中,会有其他位置的连接点)
- AOP联盟为增强定义了org.aopalliance.aop.Advice接口,是所有增强类的父类
-
切面 Aspect
- 有切点和增强组成,既包括横切逻辑的定义,同时包括连接点的定义
-
切点 Pointcut
- ClassFilter
- MethodMatcher
-
目标对象 Target
- 增强逻辑的织入目标类
-
织入 Weaving
- 将增强添加到对目标类具体连接点上的过程
-
织入方式
- 编译期织入 -- 需要特殊的Java编译器
- 类装载期织入 -- 需要特殊的类装载器
-
动态代理织入 -- 在运行期为目标类添加增强生成子类
- Spring采用这种方式
-
代理 Proxy
- 一个类被AOP织入增强后,产生一个结果类,即是融合了原生类的增强逻辑的代理类
-
代理类可以是原生类的子类或者与原生类具有相同的接口
- 所以:代理类的调用方式和原生类的调用方式相同
-
Spring AOP两种代理机制
- 基于JDK的动态代理
-
基于CGLib的动态代理 -- Code Generation Library
- CGLIB代理是生成的目标类的子类,所以类和方法不能声明为final的
- 在子类方法中采用方法拦截的技术拦截所以父类方法的调用,并顺势插入横切逻辑
- * 其实所有代理道理都是一样,就是通过代理对象去调用目标对象,并且在代理对象中做点“手脚”--加入一些其他操作。*
-
ProxyFactory
- ProxyFactoryBean
-
切面类型
-
具有切点的切面 PointcutAdvisor
- Advice
-
Pointcut
-
ClassFilter#getClassFilter
- matches
-
MethodMatcher#getMethodMatcher
- matchers
- isRuntime
-
流程切面
- 流程切点
-
复合切点切面
- 流程切点
- 引介切面 IntroductionAdvisor
-
AOP切面类型
- Advisor -- 一般切面
-
PointcutAdvisor -- 具有切点的切面
-
静态切面
- StaticMethodMatcherPointcutAdvisor
- RegexpMethodPointcutAdvisor
-
动态切面
-
静态切点检查方法
- public boolean matches(Method method, Class clazz)
- public ClassFilter getClassFilter();
-
动态检查方法
- public boolean matches(Method method, Class clazz, Object[] args)
- * DynamicMethodMatcherPointcut
-
流程切面
- 代理对象在每次调用目标类方法时,都需要判断方法调用栈中是否满足流程切点的要求
- * ControlFlowPointcut
-
复合切点切面
-
* ComposablePointcut
- 可以将多个切点以并集或交集的方式组合起来
- 没有提供直接对两个切点进行交并集运算的方法,而只提供了切点和ClassFilter及MethodMatcher的复合方法
- 引介切面
- IntroductionAdvisor -- 引介切面
-
AOP增强详细
-
前置增强
- 因为Spring仅支持方法级的增强,所以MethodBeforeAdvice是目前可用的前置增强
-
后置增强
- AfterReturningAdvice
-
环绕增强
-
MethodInterceptor
- Interceptor
-
异常抛出增强
- ThrowsAdvice
-
引介增强
- 为目标类添加一个接口的实现(原理目标类没有实现这个接口,可以通过引介为目标类创建某接口的代理)
-
DelegatingIntroductionInterceptor
- IntroductionInterceptor