当前位置 主页 > 网站技术 > 代码类 >

    Spring AOP执行先后顺序实例详解

    栏目:代码类 时间:2020-01-22 18:05

    这篇文章主要介绍了Spring AOP执行先后顺序实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

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

    网上很多答案都是指定order,order越小越是最先执行,这种也不能算是错,但有些片面。

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

    通过实现org.springframework.core.Ordered接口

    @Component 
    @Aspect 
    @Slf4j 
    public class MessageQueueAopAspect1 implements Ordered{@Override 
      public int getOrder() { 
        // TODO Auto-generated method stub 
        return 2; 
      } 
       
    } 

    通过注解

    @Component 
    @Aspect 
    @Slf4j 
    @Order(1) 
    public class MessageQueueAopAspect1{ 
       
      ... 
    } 

    通过配置文件配置

    <aop:config expose-proxy="true"> 
      <aop:aspect ref="aopBean" order="0">  
        <aop:pointcut  expression="@annotation(xxx.xxx.xxx.annotation.xxx)"/>  
        <aop:around pointcut-ref="testPointcut" method="doAround" />  
        </aop:aspect>  
    </aop:config> 

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

    @Component 
    @Aspect 
    @Slf4j 
    public class MessageQueueAopAspect1 implements Ordered{ 
       
      @Resource(name="actionMessageProducer") 
      private IProducer<MessageQueueInfo> actionProducer;   
       
      @Pointcut("@annotation(com.xxx.annotation.MessageQueueRequire1)") 
      private void pointCutMethod() { 
      } 
       
      //声明前置通知 
      @Before("pointCutMethod()") 
      public void doBefore(JoinPoint point) { 
        log.info("MessageQueueAopAspect1:doBefore"); 
        return; 
      } 
     
      //声明后置通知 
      @AfterReturning(pointcut = "pointCutMethod()", returning = "returnValue") 
      public void doAfterReturning(JoinPoint point,Object returnValue) { 
        log.info("MessageQueueAopAspect1:doAfterReturning"); 
      } 
     
      //声明例外通知 
      @AfterThrowing(pointcut = "pointCutMethod()", throwing = "e") 
      public void doAfterThrowing(Exception e) { 
        log.info("MessageQueueAopAspect1:doAfterThrowing"); 
      } 
     
      //声明最终通知 
      @After("pointCutMethod()") 
      public void doAfter() { 
        log.info("MessageQueueAopAspect1:doAfter"); 
      } 
     
      //声明环绕通知 
      @Around("pointCutMethod()") 
      public Object doAround(ProceedingJoinPoint pjp) throws Throwable { 
        log.info("MessageQueueAopAspect1:doAround-1"); 
        Object obj = pjp.proceed(); 
        log.info("MessageQueueAopAspect1:doAround-2"); 
        return obj; 
      } 
       
      @Override 
      public int getOrder() { 
        return 1001; 
      } 
    } 
    @Component 
    @Aspect 
    @Slf4j 
    public class MessageQueueAopAspect2 implements Ordered{ 
       
      @Resource(name="actionMessageProducer") 
      private IProducer<MessageQueueInfo> actionProducer;   
       
      @Pointcut("@annotation(com.xxx.annotation.MessageQueueRequire2)") 
      private void pointCutMethod() { 
      } 
       
       
      //声明前置通知 
      @Before("pointCutMethod()") 
      public void doBefore(JoinPoint point) { 
        log.info("MessageQueueAopAspect2:doBefore"); 
        return; 
      } 
     
      //声明后置通知 
      @AfterReturning(pointcut = "pointCutMethod()", returning = "returnValue") 
      public void doAfterReturning(JoinPoint point,Object returnValue) { 
        log.info("MessageQueueAopAspect2:doAfterReturning"); 
      } 
     
      //声明例外通知 
      @AfterThrowing(pointcut = "pointCutMethod()", throwing = "e") 
      public void doAfterThrowing(Exception e) { 
        log.info("MessageQueueAopAspect2:doAfterThrowing"); 
      } 
     
      //声明最终通知 
      @After("pointCutMethod()") 
      public void doAfter() { 
        log.info("MessageQueueAopAspect2:doAfter"); 
      } 
     
      //声明环绕通知 
      @Around("pointCutMethod()") 
      public Object doAround(ProceedingJoinPoint pjp) throws Throwable { 
        log.info("MessageQueueAopAspect2:doAround-1"); 
        Object obj = pjp.proceed(); 
        log.info("MessageQueueAopAspect2:doAround-2"); 
        return obj; 
      } 
       
      @Override 
      public int getOrder() { 
        return 1002; 
      } 
    }