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

网友投稿 299 2022-12-15


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

这篇文章主要介绍了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,看看究竟。

@Component

@Aspect

@Slf4j

public class MessageQueueAopAspect1 implements Ordered{

@Resource(name="actionMessageProducer") http://

private IProducer 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("pJjwjoBointCutMethod()")

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 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 doAfterRJjwjoBeturning(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;

}

}

@Transactional(propagation=Propagation.REQUIRES_NEW)

@MessageQueueRequire1

@MessageQueueRequire2

public PnrPaymentErrCode bidLoan(String id){

...

}

看看执行结果:

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

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

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

如果我们要在同一个方法事务提交后执行自己的AOP,那么把事务的AOP order设置为2,自己的AOP order设置为1,然后在doAfterReturn里边处理自己的业务逻辑。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Spring Boot使用过滤器Filter过程解析
下一篇:Spring Boot拦截器和过滤器实例解析
相关文章

 发表评论

暂时没有评论,来抢沙发吧~