Spring AOP你一定知道,那么你知道AOP的全部通知顺序吗?Spring或SpringBoot的版本对AOP的通知顺序有无影响?
AOP常用注解
- @Before:前置通知,在目标方法执行之前通知。
- @After:后置通知,在目标方法之后执行,始终执行。
- @AfterReturning:返回后通知,目标方法结束前执行,异常不执行。
- @AfterThrowing:异常通知,出现异常时执行。
- @Around:环绕通知,环绕目标方法执行。
AOP案例
接口及实现
public interface CalcService {
int div(int x, int y);
}
@Service
@Slf4j
public class CalcServiceImpl implements CalcService {
@Override
public int div(int x, int y) {
int result = x / y;
log.info("调用CalcService,计算结果是:{}", result);
return result;
}
}
切面
@Aspect
@Component
@Slf4j
public class MyAspect {
@Before("execution(public int com.icode.aop.CalcServiceImpl.*(..))")
public void beforeNotify() {
log.info("@Before前置通知");
}
@After("execution(public int com.icode.aop.CalcServiceImpl.*(..))")
public void afterNotify() {
log.info("@After后置通知");
}
@AfterReturning("execution(public int com.icode.aop.CalcServiceImpl.*(..))")
public void afterReturningNotify() {
log.info("@AfterReturning返回后通知");
}
@AfterThrowing("execution(public int com.icode.aop.CalcServiceImpl.*(..))")
public void afterThrowingNotify() {
log.info("@AfterThrowing异常通知");
}
@Around("execution(public int com.icode.aop.CalcServiceImpl.*(..))")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
Object result = null;
log.info("环绕通知之前");
result = proceedingJoinPoint.proceed();
log.info("环绕通知之后");
return result;
}
}
测试类
@SpringBootTest
@Slf4j
@RunWith(SpringRunner.class)
public class AopTest {
@Autowired
private CalcService calcService;
@Test
public void test4() {
log.info("Spring版本:{},SpringBoot版本:{}", SpringVersion.getVersion(), SpringBootVersion.getVersion());
//正常时AOP通知顺序
calcService.div(10, 2);
//异常时AOP通知顺序
calcService.div(10, 0);
}
}
将SpringBoot版本设置为1.5.9,程序正常运行的测试结果为
2021-02-27 19:44:21.230 INFO 1060 --- [ main] com.icode.AopTest : Spring版本:4.3.13.RELEASE,SpringBoot版本:1.5.9.RELEASE
2021-02-27 19:44:21.235 INFO 1060 --- [ main] com.icode.aop.MyAspect : 环绕通知之前
2021-02-27 19:44:21.235 INFO 1060 --- [ main] com.icode.aop.MyAspect : @Before前置通知
2021-02-27 19:44:21.235 INFO 1060 --- [ main] com.icode.aop.CalcServiceImpl : 调用CalcService,计算结果是:5
2021-02-27 19:44:21.235 INFO 1060 --- [ main] com.icode.aop.MyAspect : 环绕通知之后
2021-02-27 19:44:21.235 INFO 1060 --- [ main] com.icode.aop.MyAspect : @After后置通知
2021-02-27 19:44:21.235 INFO 1060 --- [ main] com.icode.aop.MyAspect : @AfterReturning返回后通知
程序异常运行的测试结果为
2021-02-27 23:21:38.348 INFO 12596 --- [ main] com.icode.AopTest : Spring版本:4.3.13.RELEASE,SpringBoot版本:1.5.9.RELEASE
2021-02-27 23:21:38.352 INFO 12596 --- [ main] com.icode.aop.MyAspect : 环绕通知之前
2021-02-27 23:21:38.352 INFO 12596 --- [ main] com.icode.aop.MyAspect : @Before前置通知
2021-02-27 23:21:38.353 INFO 12596 --- [ main] com.icode.aop.MyAspect : @After后置通知
2021-02-27 23:21:38.353 INFO 12596 --- [ main] com.icode.aop.MyAspect : @AfterThrowing异常通知
java.lang.ArithmeticException: / by zero
将SpringBoot版本设置为2.3.3,程序正常运行的测试结果为
2021-02-27 23:23:03.970 INFO 14416 --- [ main] com.icode.AopTest : Spring版本:5.2.8.RELEASE,SpringBoot版本:2.3.3.RELEASE
2021-02-27 23:23:03.975 INFO 14416 --- [ main] com.icode.aop.MyAspect : 环绕通知之前
2021-02-27 23:23:03.975 INFO 14416 --- [ main] com.icode.aop.MyAspect : @Before前置通知
2021-02-27 23:23:03.985 INFO 14416 --- [ main] com.icode.aop.CalcServiceImpl : 调用CalcService,计算结果是:5
2021-02-27 23:23:03.986 INFO 14416 --- [ main] com.icode.aop.MyAspect : @AfterReturning返回后通知
2021-02-27 23:23:03.986 INFO 14416 --- [ main] com.icode.aop.MyAspect : @After后置通知
2021-02-27 23:23:03.986 INFO 14416 --- [ main] com.icode.aop.MyAspect : 环绕通知之后
程序异常运行的测试结果为
2021-02-27 23:22:36.133 INFO 13916 --- [ main] com.icode.AopTest : Spring版本:5.2.8.RELEASE,SpringBoot版本:2.3.3.RELEASE
2021-02-27 23:22:36.137 INFO 13916 --- [ main] com.icode.aop.MyAspect : 环绕通知之前
2021-02-27 23:22:36.137 INFO 13916 --- [ main] com.icode.aop.MyAspect : @Before前置通知
2021-02-27 23:22:36.147 INFO 13916 --- [ main] com.icode.aop.MyAspect : @AfterThrowing异常通知
2021-02-27 23:22:36.148 INFO 13916 --- [ main] com.icode.aop.MyAspect : @After后置通知
java.lang.ArithmeticException: / by zero