4、申明通知
通知的类型
Before
在目标方法之前执行,如果发生异常,会阻止业务代码的执行
AfterReturning
跟Before对应,在目标方法完全执行后(return后)再执行
AfterThrowing
方法抛出异常这个通知仍然会执行(这里的方法既可以是目标方法,也可以是我们定义的通知)
After(Finally)
切记,跟Before对应的是AfterReturning,一个在目标方法还没执行前执行,一个在目标方法完全执行后(return后)再执行,这个After类型的通知类型我们在编写代码时的Finally,即使方法抛出异常这个通知仍然会执行(这里的方法既可以是目标方法,也可以是我们定义的通知)。
一般我们使用After类型的通知都是为了完成资源的释放或者其它类似的目的
Around
最强大的通知类型,可以包裹目标方法,其可以传入一个ProceedingJoinPoint用于调用业务模块的代码,无论是调用前逻辑还是调用后逻辑,都可以在该方法中编写,甚至其可以根据一定的条件而阻断业务模块的调用,可以更改目标方法的返回值
实际应用
@Aspect @Component public class DmzAnnotationAspect { @Pointcut("execution(public * *(..))") private void executionPointcut() {} @Pointcut("@annotation(com.spring.study.springfx.aop.annotation.DmzAnnotation)") private void annotationPointcut() { } // 可以组合使用定义好的切点 // 表示同时匹配满足两者 @Pointcut("executionPointcut() && annotationPointcut()") private void annotationPointcutAnd() {} // 满足其中之一即可 @Pointcut("executionPointcut() || annotationPointcut()") private void annotationPointcutOr() {} // 不匹配即可 @Pointcut("!executionPointcut()") private void annotationPointcutNot() {} }
通知中的参数
在上面应用的例子中,只有在环绕通知的方法上我添加了一个ProceedingJoinPoint类型的参数。这个ProceedingJoinPoint意味着当前执行中的方法,它继承了JoinPoint接口。
JoinPoint
JoinPoint可以在任意的通知方法上作为第一个参数申明,代表的时候通知所应用的切点(也就是目标类中的方法),它提供了以下几个方法:
- getArgs(): 返回当前的切点的参数
- getThis(): 返回代理对象
- getTarget(): 返回目标对象
- getSignature(): 返回这个目标类中方法的描述信息,比如修饰符,名称等
ProceedingJoinPoint
ProceedingJoinPoint在JoinPoint的基础上多提供了两个方法
- proceed():直接执行当前的方法,基于此,我们可以在方法的执行前后直接加入对应的业务逻辑
- proceed(Object[] args):可以改变当前执行方法的参数,然后用改变后的参数执行这个方法
通知的排序
当我们对于一个切点定义了多个通知时,例如,在一个切点上同时定义了两个before类型的通知。这个时候,为了让这两个通知按照我们期待的顺序执行,我们需要在切面上添加org.springframework.core.annotation.Order注解或者让切面实现org.springframework.core.Ordered接口。如下:
@Aspect @Component @Order(-1) public class DmzFirstAspect { // ... } @Aspect @Component @Order(0) public class DmzSecondAspect { // ... }