Pro Spring 3读书笔记(二) - 18965050/pro-spring-3 GitHub Wiki

AOP

概念

  • join point: 连接点. 是程序执行中的一个精确执行点,例如类中的一个方法
  • advice: 通知. 在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知
  • point cut: join point的集合
  • aspect: advice和point cut的集合
  • weaving: 组装aspect来创建一个被通知对象
  • target: 被织入的对象
  • introduction: 添加方法或字段到被通知的类

AOP类型

  • 静态AOP(static aop): aop织入在编译时期完成
  • 动态AOP(dynamic aop): aop织入在运行时期完成

Spring中的Aspect

Spring提供了一个接口:Advisor,用于表示aspect.在spring内部, 有两种advisor:

  • IntroductionAdvisor:只能应用于类级别的拦截,只能使用Introduction型的Advice
  • PointcutAdvisor: 可以使用任何类型的Pointcut,以及差不多任何类型的Advice

ProxyFactory

ProxyFactory用于将advice织入到target中,ProxyFactory在织入代理过程中会代理给DefaultAopProxyFactory去做. 而DefaultAopProxyFactory又会根据系统的设置具体代理给JdkDynamicAopProxy或Cglib2AopProxy去执行.

使用CGLIB方式代理, 不需要定义接口, 但要注意:

  • 通知方法不能为final方法, 因为final方法不能在子类被覆盖
  • 会产生两次构造器调用,第一次是目标类的构造器调用,第二次是CGLIB生成的代理类的构造器调用。如果需要CGLIB代理方法,请确保两次构造器调用不影响应用

Spring支持六种advices: advice类型-1 advice类型-2

它们之间的层次结构为: advice类结构

PointCut

spring3.1提供的PointCut实现有: PointCut实现-1 PointCut实现-2 PointCut类结构

理解Proxy

spring内部的两种代理方式: jdk和cglib. jdk必须需要有接口,而cglib则不需要. ProxyFactory.setProxyTargetClass(true)可明确指出使用cglib 代理方式

PointCut高级使用

  • ControlFlowPointcut: 流程切入点PointCut. 用于我们对一个方法进行切入通知,但只有这个方法在一个特定方法中被调用的时候执行通知
  • ComposablePointcut: ComposablePointcut提供有union()和intersection()方法, 用于不同pointcut进行"与","或"的操作

introduction

introduction可以给现有类动态添加接口的功能. 这是通过实现IntroductionInterceptor接口来完成的(绝大多数情况下, 我们继承其子类DelegatingIntroductionInterceptor)

配置声明式的AOP

配置声明式的AOP有三种方式:

  • 使用ProxyFactoryBean
  • 使用Spring aop 名词空间
  • 使用 @AspectJ 风格的注解

spring aop名词空间配置:

  • <aop:config> : 根标签, 包含<aop:pointcut>、<aop:advisor>、<aop:aspect> 标签, 标签顺序不可变
  • <aop:pointcut>:用来定义切入点,该切入点可以重用;
  • <aop:advisor>:用来定义只有一个通知和一个切入点的切面;
  • <aop:aspect>:用来定义切面,该切面可以包含多个切入点和通知,而且标签内部的通知和切入点定义是无序的;和advisor的区别就在此,advisor只包含一个通知和一个切入点。

@AspectJ 注解配置:

  • spring默认不支持aspectj注解方式的切面配置, 需在配置文件中添加
<aop:aspectj-autoproxy   proxy-target-class="true" /> <!--如果使用CGLIB, proxy-target-class属性配置为true -->
  • @Aspect
  • @Pointcut
  • 通知配置, 包括:
    • @Before
    • @AfterReturning
    • @After
    • @Around
    • AfterThrowing
  • @DeclareParents: introduction类型的aop

上述方式二(aop namespace)和方式三(aspectj annotation)有些区别:

  1. 方式二只适用于"singleton" bean

  2. 方式二不能对多个pointcut定义advice

通知执行顺序

对于同一切入点(pointcut),通知执行顺序可分为:

  • 同一切面中的通知执行顺序: spring模块-3
  • 不同切面的通知执行顺序: 可由Ordered来确定顺序 spring模块-3

AOP实例模型

AOP实例模型分为三类:

  • singleton:即切面只会有一个实例
  • perthis:每个切入点表达式匹配的连接点对应的AOP对象都会创建一个新切面实例
  • pertarget:每个切入点表达式匹配的连接点对应的目标对象都会创建一个新的切面实例
⚠️ **GitHub.com Fallback** ⚠️