前言
最近在学习SpringBoot的AOP执行顺序时,发现自己的运行结果与网上的有些不太一致,经查证,其实原由来自Spring版本的更新,详见官网5.2.7版本的解释。目前我使用的SpringBoot版本为2.5.2,对应Spring版本为5.3.8,而教程的SpringBoot版本为2.1.4.RELEASE,对应Spring版本为5.1.6.RELEASE,显然两者分别为5.2.7修改前后的版本,AOP顺序不一样也就显而易见了。
旧版本AOP顺序
POM依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--Spring MVC-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Spring AOP-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
TestController:
@RestController
@RequestMapping("test")
public class TestController {
@GetMapping
public String user() {
System.out.println("[Controller]执行controller方法");
return "正常执行";
}
@GetMapping("ex")
public String e() {
System.out.println("[Controller]执行controller方法:异常之前");
int i = 1 / 0;
System.out.println("[Controller]执行controller方法:异常之后");
return "发生异常";
}
}
AOP:
@Aspect
@Component
public class LogAop {
@Pointcut("execution(* com.example.testproject.controller.*.*(..))")
public void pointcut() {
}
@Before("pointcut()")
public void before() {
System.out.println("[AOP]执行前置通知");
}
@After("pointcut()")
public void after() {
System.out.println("[AOP]执行后置通知");
}
@Around("pointcut()")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("[AOP]执行环绕前通知");
Object result = proceedingJoinPoint.proceed();
System.out.println("[AOP]执行环绕后通知");
return result;
}
@AfterReturning("pointcut()")
public void afterReturning() {
System.out.println("[AOP]执行返回通知");
}
@AfterThrowing("pointcut()")
public void afterThrowing() {
System.out.println("[AOP]执行异常通知");
}
}
正常执行结果:
[AOP]执行环绕前通知
[AOP]执行前置通知
[Controller]执行controller方法
[AOP]执行环绕后通知
[AOP]执行后置通知
[AOP]执行返回通知
异常执行结果:
[AOP]执行环绕前通知
[AOP]执行前置通知
[Controller]执行controller方法:异常之前
[AOP]执行后置通知
[AOP]执行异常通知
新版本AOP顺序
代码程序完全同上,只是将版本改成2.5.2,得到如下结果
正常执行结果:
[AOP]执行环绕前通知
[AOP]执行前置通知
[Controller]执行controller方法
[AOP]执行返回通知
[AOP]执行后置通知
[AOP]执行环绕后通知
异常执行结果:
[AOP]执行环绕前通知
[AOP]执行前置通知
[Controller]执行controller方法:异常之前
[AOP]执行异常通知
[AOP]执行后置通知
流程对比
旧版本:
新版本: