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裏邊處理本身的業務邏輯。

相關文章
相關標籤/搜索