多个切面的执行顺序
如果我们在同一个方法使用多个AOP注解,我们如何指定他们的执行顺序呢?
可以通过指定切面的order,order越小越是最先执行。
配置切面执行顺序的三种方式:
一.通过实现Ordered接口
@Component @Aspect @Slf4j public class MessageQueueAopAspect1 implements Ordered{@Override public int getOrder() { // TODO Auto-generated method stub return 2; } }
二.配置文件配置
<aop:config expose-proxy="true">
<aop:aspect ref="aopBean" order="0">
<aop:pointcut />
<aop:around pointcut-ref="testPointcut" method="doAround" />
</aop:aspect>
</aop:config>
三.@Order注解指定
@Component @Aspect @Slf4j @Order(1) public class MessageQueueAopAspect1{ ... }
通知的执行顺序
Advice :通知(建言),在切面的某个特定的连接点(增强方法)(Join point)上执行的操作。
分为:
测试示例
创建两个自定义注解
自定义注解1
1 /** 2 * 自定义注解1 3 * @author JustJavaIt 4 * @date 2022/3/20 21:09 5 */ 6 @Target(ElementType.METHOD) 7 @Retention(RetentionPolicy.RUNTIME) 8 @Documented 9 public @interface Annotation1 { 10 }
自定义注解2
1 /** 2 * 自定义注解2 3 * @author JustJavaIt 4 * @date 2022/3/20 21:09 5 */ 6 @Target(ElementType.METHOD) 7 @Retention(RetentionPolicy.RUNTIME) 8 @Documented 9 public @interface Annotation2 { 10 11 }
定义两个切面
切面1
1 /** 2 * 切面1 order比较小 先执行 3 * @author JustJavaIt 4 * @date 2022/3/20 21:13 5 */ 6 @Component 7 @Aspect 8 @Slf4j 9 @Order(1) 10 public class AopAspect1 { 11 12 @Pointcut("@annotation(com.study.frame.aopTest.Annotation1)") 13 private void pointCutMethod() { 14 } 15 16 /** 17 * 前置通知: 在一个方法执行之前,执行通知。 18 * 模拟执行权限检查 19 * @param point 20 */ 21 @Before("pointCutMethod()") 22 public void doBefore(JoinPoint point) { 23 log.info("AopAspect1:@Before,目标方法为:{},参数为{}", 24 point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName(), 25 Arrays.toString(point.getArgs())); 26 } 27 28 /** 29 * 返回后通知: 在一个方法执行之后,只有在方法成功完成时,才能执行通知。如果抛异常了,那么不会执行通知(可打开测试Controller注释)。 30 * @param point 31 * @param returnValue 32 */ 33 @AfterReturning(pointcut = "pointCutMethod()", returning = "returnValue") 34 public void doAfterReturning(JoinPoint point,Object returnValue) { 35 log.info("AopAspect1:@AfterReturning,方法返回值为:{}", returnValue); 36 } 37 38 /** 39 * 抛出异常后通知: 在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知。 40 * @param e 41 */ 42 @AfterThrowing(pointcut = "pointCutMethod()", throwing = "e") 43 public void doAfterThrowing(Exception e) { 44 log.info("AopAspect1:@AfterThrowing"); 45 } 46 47 /** 48 * 后置通知:在一个方法执行之后,不考虑其结果,执行通知。 49 */ 50 @After("pointCutMethod()") 51 public void doAfter() { 52 log.info("AopAspect1:@After"); 53 } 54 55 /** 56 * 环绕通知: 在建议方法调用之前和之后,执行通知。 57 * @param pjp 58 * @return 59 * @throws Throwable 60 */ 61 @Around("pointCutMethod()") 62 public Object doAround(ProceedingJoinPoint pjp) throws Throwable { 63 log.info("AopAspect1:@Around-1"); 64 Object obj = pjp.proceed(); 65 log.info("AopAspect1:@Around-2"); 66 return obj; 67 } 68 }