Spring AOP中实例详解的执行顺序是怎样的?

2026-05-28 09:451阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1441个文字,预计阅读时间需要6分钟。

Spring AOP中实例详解的执行顺序是怎样的?

本文主要介绍了Spring AOP执行先后顺序实例详解,通过示例代码展示,内容非常详细。对于想要学习或工作的朋友,具有一定的参考价值。以下为部分内容:

Spring AOP执行先后顺序实例详解,通过示例代码展示,内容详细,对于想要学习或工作的朋友具有一定的参考价值。以下为部分内容:

众周知,Spring框架中AOP(面向切面编程)是一种强大的编程范式,可以让我们在不修改业务逻辑代码的情况下,实现横切关注点的分离。本文将详细讲解Spring AOP的执行先后顺序,并通过示例代码进行说明。

在Spring AOP中,切面(Aspect)由切点(Pointcut)和通知(Advice)组成。切点用于定位目标方法,通知则用于在目标方法执行前后执行特定的逻辑。Spring AOP提供了五种类型的通知:

1. 前置通知(Before):在目标方法执行之前执行;

2.环绕通知(Around):在目标方法执行前后执行,可以控制目标方法的执行;

3.后置通知(After):在目标方法执行之后执行;

4.返回通知(AfterReturning):在目标方法正常返回后执行;

5.异常通知(AfterThrowing):在目标方法抛出异常后执行。

下面通过一个示例代码来展示Spring AOP的执行先后顺序:

java

import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.springframework.stereotype.Component;

@Aspect@Componentpublic class MyAspect {

@Before(execution(* com.example.service.*.*(..))) public void beforeAdvice() { System.out.println(Before advice executed); }

@After(execution(* com.example.service.*.*(..))) public void afterAdvice() { System.out.println(After advice executed); }

@AfterReturning(execution(* com.example.service.*.*(..))) public void afterReturningAdvice() { System.out.println(After returning advice executed); }

@AfterThrowing(execution(* com.example.service.*.*(..))) public void afterThrowingAdvice() { System.out.println(After throwing advice executed); }}

在这个示例中,我们定义了一个切面`MyAspect`,其中包含了五种类型的通知。通过`execution`表达式,我们指定了切点为`com.example.service`包下的所有方法。

当执行目标方法时,Spring AOP会按照以下顺序执行通知:

1. 前置通知(Before)

2.目标方法

3.后置通知(After)

4.返回通知(AfterReturning)

5.异常通知(AfterThrowing)

Spring AOP中实例详解的执行顺序是怎样的?

以上就是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:config expose-proxy="true"> <aop:aspect ref="aopBean" order="0"> <aop:pointcut id="testPointcut" 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; } }

@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里边处理自己的业务逻辑。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易盾网络。

本文共计1441个文字,预计阅读时间需要6分钟。

Spring AOP中实例详解的执行顺序是怎样的?

本文主要介绍了Spring AOP执行先后顺序实例详解,通过示例代码展示,内容非常详细。对于想要学习或工作的朋友,具有一定的参考价值。以下为部分内容:

Spring AOP执行先后顺序实例详解,通过示例代码展示,内容详细,对于想要学习或工作的朋友具有一定的参考价值。以下为部分内容:

众周知,Spring框架中AOP(面向切面编程)是一种强大的编程范式,可以让我们在不修改业务逻辑代码的情况下,实现横切关注点的分离。本文将详细讲解Spring AOP的执行先后顺序,并通过示例代码进行说明。

在Spring AOP中,切面(Aspect)由切点(Pointcut)和通知(Advice)组成。切点用于定位目标方法,通知则用于在目标方法执行前后执行特定的逻辑。Spring AOP提供了五种类型的通知:

1. 前置通知(Before):在目标方法执行之前执行;

2.环绕通知(Around):在目标方法执行前后执行,可以控制目标方法的执行;

3.后置通知(After):在目标方法执行之后执行;

4.返回通知(AfterReturning):在目标方法正常返回后执行;

5.异常通知(AfterThrowing):在目标方法抛出异常后执行。

下面通过一个示例代码来展示Spring AOP的执行先后顺序:

java

import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.springframework.stereotype.Component;

@Aspect@Componentpublic class MyAspect {

@Before(execution(* com.example.service.*.*(..))) public void beforeAdvice() { System.out.println(Before advice executed); }

@After(execution(* com.example.service.*.*(..))) public void afterAdvice() { System.out.println(After advice executed); }

@AfterReturning(execution(* com.example.service.*.*(..))) public void afterReturningAdvice() { System.out.println(After returning advice executed); }

@AfterThrowing(execution(* com.example.service.*.*(..))) public void afterThrowingAdvice() { System.out.println(After throwing advice executed); }}

在这个示例中,我们定义了一个切面`MyAspect`,其中包含了五种类型的通知。通过`execution`表达式,我们指定了切点为`com.example.service`包下的所有方法。

当执行目标方法时,Spring AOP会按照以下顺序执行通知:

1. 前置通知(Before)

2.目标方法

3.后置通知(After)

4.返回通知(AfterReturning)

5.异常通知(AfterThrowing)

Spring AOP中实例详解的执行顺序是怎样的?

以上就是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:config expose-proxy="true"> <aop:aspect ref="aopBean" order="0"> <aop:pointcut id="testPointcut" 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; } }

@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里边处理自己的业务逻辑。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持易盾网络。