SpringAOP的切面执行顺序在Spring4和Spring5中有什么区别?

准备测试代码

  • 一个测试接口
public interface UserService {void doProcess(long userId);}
  • 以及他的实现类
【SpringAOP的切面执行顺序在Spring4和Spring5中有什么区别?】@Servicepublic class DefaultUserService implements UserService {@Overridepublic void doProcess(long userId) {if (userId <= 0) {throw new IllegalArgumentException("userId <= 0");}}}
  • 下面是切面类
@Aspect@Componentpublic class UserServiceLogAspect {@Pointcut("execution(public * com.example.springaop.service.impl.DefaultUserService.*(..))")public void pointcut() {}@Before("pointcut()")public void before(JoinPoint joinPoint) {System.out.println("++++++++++> @Before " + joinPoint.getSignature().getName() + Arrays.toString(joinPoint.getArgs()));}@After("pointcut()")public void after(JoinPoint joinPoint) {System.out.println("<++++++++++ @After " + joinPoint.getSignature().getName() + Arrays.toString(joinPoint.getArgs()));}@AfterReturning("pointcut()")public void afterReturning(JoinPoint joinPoint) {System.out.println("<++++++++++ @AfterReturning " + joinPoint.getSignature().getName() + Arrays.toString(joinPoint.getArgs()));}@AfterThrowing(value = https://www.isolves.com/it/cxkf/kj/2022-03-03/"pointcut()", throwing = "throwable")public void afterThrowing(JoinPoint joinPoint, Throwable throwable) {System.err.println("<++++++++++ @AfterThrowing "+ joinPoint.getSignature().getName() + Arrays.toString(joinPoint.getArgs())+ " errMsg=[" + throwable.getMessage() + "]");}@Around("pointcut()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {final String sig = joinPoint.getSignature().getName() + Arrays.toString(joinPoint.getArgs());Object result = null;System.out.println("----------> @Around##Before " + sig);try {result = joinPoint.proceed();} catch (Throwable e) {System.err.println("<---------- @Around##AfterThrowing " + sig + " errMsg=[" + e.getMessage() + "]");throw e; // re-throw}System.out.println("<---------- @Around##After " + sig);return result;}}基于以上的切面逻辑,在 UserService#doProcess(long) 方法执行前后以及异常情况下的各个切面的执行顺序是怎样的呢?
在Spring5中的结果执行下面测试代码,观察输出:
@SpringBootTestclass SpringAopApplicationTestsSpring5 {@Autowiredprivate UserService userService;// 测试正常情况@Testpublic void testNormally() {System.out.println("SpringBootVersion: " + SpringBootVersion.getVersion() + "tSpringVersion: " + SpringVersion.getVersion() + "n");this.userService.doProcess(1);}// 测试异常情况@Testpublic void testError() {System.out.println("SpringBootVersion: " + SpringBootVersion.getVersion() + "tSpringVersion: " + SpringVersion.getVersion() + "n");this.userService.doProcess(-1);}}
  • 正常情况输出如下:
SpringBootVersion: 2.5.7SpringVersion: 5.3.13----------> @Around##Before doProcess[1]++++++++++> @Before doProcess[1]<++++++++++ @AfterReturning doProcess[1]<++++++++++ @After doProcess[1]<---------- @Around##After doProcess[1]
  • 异常情况输出如下:
SpringBootVersion: 2.5.7SpringVersion: 5.3.13----------> @Around##Before doProcess[-1]++++++++++> @Before doProcess[-1]<++++++++++ @AfterThrowing doProcess[-1] errMsg=[userId <= 0]<++++++++++ @Around##AfterThrowing doProcess[-1] errMsg=[userId <= 0]<++++++++++ @After doProcess[-1]<---------- @Around##After doProcess[-1]在Spring4中的结果执行下面测试代码,观察输出:
@SpringBootTest@RunWith(SpringRunner.class)public class SpringAopApplicationTestsSpring4 {@Autowiredprivate UserService userService;@Testpublic void testNormally() {System.out.println("SpringBootVersion: " + SpringBootVersion.getVersion() + "tSpringVersion: " + SpringVersion.getVersion() + "n");this.userService.doProcess(1);}@Testpublic void testError() {System.out.println("SpringBootVersion: " + SpringBootVersion.getVersion() + "tSpringVersion: " + SpringVersion.getVersion() + "n");this.userService.doProcess(-1);}}
  • 正常情况输出如下:
SpringBootVersion: 1.5.9.RELEASESpringVersion: 4.3.13.RELEASE----------> @Around##Before doProcess[1]++++++++++> @Before doProcess[1]<---------- @Around##After doProcess[1]<++++++++++ @After doProcess[1]<++++++++++ @AfterReturning doProcess[1]
  • 异常情况输出如下:
SpringBootVersion: 1.5.9.RELEASESpringVersion: 4.3.13.RELEASE----------> @Around##Before doProcess[-1]++++++++++> @Before doProcess[-1]<++++++++++ @After doProcess[-1]<---------- @Around##AfterThrowing doProcess[-1] errMsg=[userId <= 0]<++++++++++ @AfterThrowing doProcess[-1] errMsg=[userId <= 0]


推荐阅读