我有一个 AspectJ 配置,其中包含一个用于测量目标方法执行时间的 @Around 建议。但是,执行时间是在 @AfterReturning 建议之后记录的,这不是所需的顺序。
@Aspect
@Component
public class LoggingAspectUsingPointcut {
@Pointcut("execution(* com.sam.aspect.pointcut.controller.UsingPointcutController.*(..))")
public void controllerMethods() {}
@Before("controllerMethods()")
public void logBefore() {
System.out.println("Method is about to be called");
}
@Around("controllerMethods()")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Around advice start");
long start = System.currentTimeMillis();
Object proceed = joinPoint.proceed(); // Proceed with the method execution
long executionTime = System.currentTimeMillis() - start;
System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");
System.out.println("Around Advice End");
return proceed;
}
@After("controllerMethods()")
public void logAfter() {
System.out.println("Method has been called");
}
@AfterReturning(pointcut = "execution(* com.sam.aspect.pointcut.controller.UsingPointcutController .*(..))", returning = "result")
public void logAfterReturning(Object result) {
System.out.println("Method executed successfully." + result);
}
}
我预期的顺序是:
- @Around pre-method(在执行proceed()之前)
- @前
- 目标方法执行(proceed())
- @Around post-method(执行时响应)
- @AfterReturning
- @后
相反,我得到的是:
- @Around-已执行
- @Before-已执行
- 目标方法-已执行
- @AfterReturning-已执行
- @After-执行
- @Around post-method -已执行但未按所需顺序执行
输出:
Around advice start
Method is about to be called
Method executed successfully.[Record 1, Record 2, Record 3, Record 4, Record 5, Record 6, Record 7, Record 8, Record 9, Record 10]
Method has been called
List com.sam.aspect.pointcut.controller.UsingPointcutController.getData() executed in 13ms
Around Advice End
我在这里错过了什么?如何确保在 @AfterReturning 和 @After 建议之前记录执行时间?
Spring Boot 3.3.3。类已使用 @Aspect 和 @Component 正确注释。此外,确保在应用程序中配置了 @EnableAspectJAutoProxy。
您描述的行为记录在 Spring 手册的“Advice Ordering”一章中。请特别注意以下部分:
即,
@Around
在进入时首先运行,在离开时最后运行。因此,您的方面逻辑在概念上是错误的。我建议将之前/之后的建议折叠到周围建议中,添加一些 try-catch-finally 以获得您想要的行为。或者,您可以将方面拆分为两个方面,并确保使用@Order
正确的方式使计时方面的运行优先级低于日志记录方面。