AOP(面向切面编程,Aspect-Oriented Programming)是一种新的方法论,是对OOP(面向对象编程,Object-Oriented Programming)的补充。
一个系统可以看成是由若干关注点组成的,这些关注点分为:核心关注点 和 横切关注点。一个核心关注点对应一个业务逻辑。而横切关注点是对 所有业务模块共有需求的 抽取。
AOP是将横切关注点模块化成切面,然后在运行时,将切面织入到业务方法。因此,在AOP中主要编程对象是切面(aspect)
在Spring中有两种方式使用切面:
<beans>
根元素中:<aop:aspectj-autoproxy>
元素:<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<aop:aspectj-autoproxy>
元素时,会自动为 与AspectJ切面 相匹配的Bean创建代理。@Aspect
注解
@Before
、@After
、@AfterReturning
、@AfterThrowing
或@Around
注解
@Before
- 前置通知,在方法执行之前执行@After
- 后置通知,在方法执行之后执行
@AfterReturning
- 返回通知,在方法返回结果之后执行
returning
属性添加到@AfterReturning
注解中pointcut
属性中@AfterThrowing
- 异常通知,在方法抛出异常之后执行
throwing
属性添加到@AfterThrowing
注解中@Around
- 环绕通知,围绕着方法执行
ProceedingJoinPoint
,它是JoinPoint的子接口,允许控制何时执行以及是否执行连接点ProceedingJoinPoint
的proceed()
方法,来执行被代理的方法。如果忘记这样做就会导致环绕通知被执行了,但是目标方法没有被执行例1-使用AspectJ注解以及通过JoinPoint参数访问连接点信息:
例2-在返回通知中访问连接点的返回值:
例3-在异常通知中,只关注特定的异常(本例中是ArithmeticException
):
例4-环绕通知示例:
execution(* cn.timd.spring.aop.IBusiness.* (..))
execution(public * IBusiness.* (..))
execution(public double IBusiness.* (..))
execution(public double IBusiness.* (double, ..))
execution(public double IBusiness.* (double, double))
Ordered
接口或者使用@Order
注解来指定Ordered
接口的时候,getOrder()
方法的返回值越小,优先级越高@Order
注解的时候,序号出现在注解中@Pointcut
注解将一个切入点声明成简单的方法。切入点的方法体通常是空的,因为将切入点定义和应用程序逻辑混在一起是不合理的例1-通过@Pointcut
注解将切入点声明成方法:
<beans>
根元素中导入aop Schema<aop:config>
元素内部。对于每个切面而言,都要创建一个<aop:aspect>
元素,来为具体的切面引用后端的Bean实例
<aop:aspect>
元素引用<aop:pointcut>
元素声明<aop:config>
或<aop:aspect>
元素内部:
<aop:config>
元素内部时,对所有切面有效<aop:aspect>
元素内部时,只对当前切面有效<aop:before>
声明前置通知<aop:after>
声明后置通知<aop:after-returning>
声明返回通知<aop:after-throwing>
声明异常通知<aop:around>
声明环绕通知pointcut-ref
属性引用切入点method
属性指定通知方法例子: