Spring多个AOP执行前后顺序

Spring声明式事务是基于AOP实现的,那么,若是咱们在同一个方法自定义多个AOP,咱们如何指定他们的执行顺序呢?spring

首先:配置AOP执行顺序的三种方式:express

1. 经过实现org.springframework.core.Ordered接口编程

1. @Component  ide

2. @Aspect  测试

3. @Slf4j  ui

4. public class MessageQueueAopAspect1 implements Ordered{@Override  接口

5.     public int getOrder() {  事务

6.         // TODO Auto-generated method stub  get

7. return 2;it

8.     }  

9.       

10. }  

2. 经过注解

1. @Component  

2. @Aspect  

3. @Slf4j  

4. @Order(1)  

5. public class MessageQueueAopAspect1{  

6.       

7.     ...  

8. }  

 

3. 经过配置文件配置

1. <aop:config expose-proxy="true">  

2.     <aop:aspect ref="aopBean" order="0">    

3.         <aop:pointcut id="testPointcut"  expression="@annotation(xxx.xxx.xxx.annotation.xxx)"/>    

4.         <aop:around pointcut-ref="testPointcut" method="doAround" />    

5.         </aop:aspect>    

6. </aop:config>  

咱们在同一个方法上加如下两个AOP,看看究竟。

1. @Component  

2. @Aspect  

3. @Slf4j  

4. public class MessageQueueAopAspect1 implements Ordered{  

5.       

6.     @Resource(name="actionMessageProducer")  

7.     private IProducer<MessageQueueInfo> actionProducer;     

8.       

9.     @Pointcut("@annotation(com.xxx.annotation.MessageQueueRequire1)")  

10.     private void pointCutMethod() {  

11.     }  

12.       

13.     //声明前置通知  

14.     @Before("pointCutMethod()")  

15.     public void doBefore(JoinPoint point) {  

16.         log.info("MessageQueueAopAspect1:doBefore");  

17.         return;  

18.     }  

19.   

20.     //声明后置通知  

21.     @AfterReturning(pointcut = "pointCutMethod()", returning = "returnValue")  

22.     public void doAfterReturning(JoinPoint point,Object returnValue) {  

23.         log.info("MessageQueueAopAspect1:doAfterReturning");  

24.     }  

25.   

26.     //声明例外通知  

27.     @AfterThrowing(pointcut = "pointCutMethod()", throwing = "e")  

28.     public void doAfterThrowing(Exception e) {  

29.         log.info("MessageQueueAopAspect1:doAfterThrowing");  

30.     }  

31.   

32.     //声明最终通知  

33.     @After("pointCutMethod()")  

34.     public void doAfter() {  

35.         log.info("MessageQueueAopAspect1:doAfter");  

36.     }  

37.   

38.     //声明环绕通知  

39.     @Around("pointCutMethod()")  

40.     public Object doAround(ProceedingJoinPoint pjp) throws Throwable {  

41.         log.info("MessageQueueAopAspect1:doAround-1");  

42.         Object obj = pjp.proceed();  

43.         log.info("MessageQueueAopAspect1:doAround-2");  

44.         return obj;  

45.     }  

46.       

47.     @Override  

48.     public int getOrder() {  

49.         return 1001;  

50.     }  

51. }  

 

1. @Component  

2. @Aspect  

3. @Slf4j  

4. public class MessageQueueAopAspect2 implements Ordered{  

5.       

6.     @Resource(name="actionMessageProducer")  

7.     private IProducer<MessageQueueInfo> actionProducer;     

8.       

9.     @Pointcut("@annotation(com.xxx.annotation.MessageQueueRequire2)")  

10.     private void pointCutMethod() {  

11.     }  

12.       

13.       

14.     //声明前置通知  

15.     @Before("pointCutMethod()")  

16.     public void doBefore(JoinPoint point) {  

17.         log.info("MessageQueueAopAspect2:doBefore");  

18.         return;  

19.     }  

20.   

21.     //声明后置通知  

22.     @AfterReturning(pointcut = "pointCutMethod()", returning = "returnValue")  

23.     public void doAfterReturning(JoinPoint point,Object returnValue) {  

24.         log.info("MessageQueueAopAspect2:doAfterReturning");  

25.     }  

26.   

27.     //声明例外通知  

28.     @AfterThrowing(pointcut = "pointCutMethod()", throwing = "e")  

29.     public void doAfterThrowing(Exception e) {  

30.         log.info("MessageQueueAopAspect2:doAfterThrowing");  

31.     }  

32.   

33.     //声明最终通知  

34.     @After("pointCutMethod()")  

35.     public void doAfter() {  

36.         log.info("MessageQueueAopAspect2:doAfter");  

37.     }  

38.   

39.     //声明环绕通知  

40.     @Around("pointCutMethod()")  

41.     public Object doAround(ProceedingJoinPoint pjp) throws Throwable {  

42.         log.info("MessageQueueAopAspect2:doAround-1");  

43.         Object obj = pjp.proceed();  

44.         log.info("MessageQueueAopAspect2:doAround-2");  

45.         return obj;  

46.     }  

47.       

48.     @Override  

49.     public int getOrder() {  

50.         return 1002;  

51.     }  

52. }  

 

1. @Transactional(propagation=Propagation.REQUIRES_NEW)  

2. @MessageQueueRequire1  

3. @MessageQueueRequire2  

4. public PnrPaymentErrCode bidLoan(String id){  

5.               ...  

6.        }  

看看执行结果:

 

从上面的测试咱们看到,确实是order越小越是最早执行,但更重要的是最早执行的最后结束。

这个不难理解,spring AOP就是面向切面编程,什么是切面,画一个图来理解下:

 

         由此得出:spring aop就是一个同心圆,要执行的方法为圆心,最外层的order最小。从最外层按照AOP一、AOP2的顺序依次执行doAround方法,doBefore方法。而后执行method方法,最后按照AOP二、AOP1的顺序依次执行doAfter、doAfterReturn方法。也就是说对多个AOP来讲,先before的,必定后after。

        若是咱们要在同一个方法事务提交后执行本身的AOP,那么把事务的AOP order设置为2,本身的AOP order设置为1,而后在doAfterReturn里边处理本身的业务逻辑。

相关文章
相关标签/搜索