AOP (Aspect-Oriented Programming)是一种特殊的编程结构,是对目前流行的OOP (Object-Oriented Programming)的一种补充。
相对于大家熟悉的OOP (Object-Oriented Programming),OOP的模块单元是class,而AOP的模块单元是aspect。
Spring框架提供了两种实现AOP的方式:
- 基于Schema的定义,详情请参考Spring中基于Schema的AOP配置详解
- 通过标注集成AspectJ
AOP的相关概念
1. aspect是一种可以横插入其他多个类的类。
Spring中的aspect不能再被自动代理,因而aspect的advice不能再是aspect,即不支持切面的切面。
aspect类中还可以包含advice, pointcut和introduction(inter-type)的定义。
2. join point是程序执行过程中的某个点,如开始执行某个方法的点,通常作为pointcut的组成部分。
3. advice是aspect中定义的方法,通常作为pointcut的组成部分,在pointcut指定的join point处被调用执行。
通常以拦截器链的方式实现
- around advice,最常用,包含join point的advice,即在join point的前后都有执行,可以阻止join point的执行
方法中调用ProceedingJoinPoint的proceed()方法表示继续执行后续方法。proceed()方法可以带Object[]参数,以改变后续方法的执行。proceed()方法的调用返回Object类型的值。
- before advice,在join point之前执行advice,但是不能阻止join point的执行
- after returning advice,join point正常退出之后执行advice
- after throwing advice,join point异常退出之后执行advice
- after (finally) advice,join point之后(无论是正常退出还是异常退出)执行advice
对于一个join point处有多个advice要执行时,情况如下:
- 对于join point之前执行的advice,优先级高的先执行
- 对于join point之后执行的advice,优先级高的后执行
- 对于不同aspect中定义的advice,必须通过@Order设置aspect不同的优先级,否则执行顺序不可预期
- 对于相同aspect中定义的advice,要么将advice分到不同的aspect,要么将advice合并为一个advice,否则执行顺序不可预期
4. pointcut是“方法名+描述join point的表达式”,定义遇到什么样的join point就会执行哪个advice。
在匹配pointcut描述的任何join point处执行advice。Spring AOP当前(4.0)只支持定义方法的时候指定pointcut,这样的方法返回值只能是void,而且必须是public的(受代理拦截机制的限制)。
execution/this/target/args/within/@target/@args/@within/@annotation
&&, ||, !组合多个pointcut描述
5. introduction(即AspectJ中的inter-type declaration)是通过@DeclareParents声明类实现指定接口。
在aspect中声明的各个advice方法,可以引用任何实现了指定接口的实现类。
@DeclareParents(value="com.xzy.myapp.service.*+", defaultImpl=DefaultUsageTracked.class)
6. target object(advised object)是插入aspect时执行的advice所作用的对象。
每个target object都要创建代理。
7. AOP proxy,AOP框架创建的对象,用以实现aspect。
8. weaving是连接aspect与其他应用类型或对象以创建target object的过程。