sunny123456

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

SpringBoot应用AOP及各注解的执行顺序

首先第一步,POM引入jar

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-aop</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>aspectj</groupId>
  7. <artifactId>aspectjweaver</artifactId>
  8. <version>1.5.3</version>
  9. </dependency>

第二步随便写一个类,然后类中写一个方法,我这里是写了一个除法运算:

  1. public class MathCalculator {
  2. public int div (int i, int j) {
  3. System.out.println("MathCalculator.div...");
  4. return i / j;
  5. }
  6. }

第三步写一个切面类:

  1. //该注解表示声明该类为一个切面类
  2. @Aspect
  3. public class LogAspects {
  4. //定义一个切点,表达式可以灵活运用,我这个表达式是表示MathCalculator类中所有的方法都进行切入
  5. @Pointcut("execution(public int com.example.demo.aop.MathCalculator.*(..))")
  6. public void pointCut () {}
  7. //方法执行开始之前
  8. @Before("pointCut()")
  9. public void logStart (JoinPoint joinPoint) {
  10. System.out.println("除法运行...参数:{"+ Arrays.asList(joinPoint.getArgs())+"}");
  11. }
  12. //方法执行开始之后
  13. @After("pointCut()")
  14. public void logEnd (JoinPoint joinPoint) {
  15. System.out.println("除法结束..." + joinPoint.getSignature().getName());
  16. }
  17. //当方法进行返回的时候,returning属性是指定方法参数中的result来接收返回参数,这样就可以修改返回参数
  18. @AfterReturning(value = "pointCut()", returning = "result")
  19. public void logReturn (JoinPoint joinPoint, Object result) {
  20. System.out.println("除法正常返回... 返回结果:{"+result+"}");
  21. }
  22. //当方法执行异常的时候,throwding是指定方法参数中的e来接收异常参数,可以查看发生的什么异常
  23. @AfterThrowing(value = "pointCut()", throwing = "e")
  24. public void logException (JoinPoint joinPoint, Exception e) {
  25. System.out.println("异常... 异常信息:{"+e+"}");
  26. }
  27. //环绕通知
  28. @Around("pointCut()")
  29. public Object logAround (ProceedingJoinPoint joinPoint) throws Throwable {
  30. //原方法执行之前会打印这个日志
  31. System.out.println("环绕通知... 开始");
  32. //执行原方法
  33. Object obj = joinPoint.proceed();
  34. //原方法执行结束,打印这行日志
  35. System.out.println("环绕通知... 结束");
  36. //返回方法返回参数
  37. return obj;
  38. }
  39. }

这里要注意一下AOP注解执行的先后顺序

  1. 环绕通知... 开始
  2. 除法运行...参数:{[1, 1]}
  3. MathCalculator.div...
  4. 环绕通知... 结束
  5. 除法结束...div
  6. 除法正常返回... 返回结果:{1}

运行的顺序是

1、@Around

2、@Before

3、原方法

4、@Around

5、@After

6、@AfterReturning

第四步,写一个配置类,记得一定要加@EnableAspectJAutoProxy注解

  1. //该配置类是为了将我们前2个类(切面类、被切面类)加入到Spring容器中
  2. @Configuration
  3. //启动AOP(一定要加这个注解,切记!!!)
  4. @EnableAspectJAutoProxy
  5. public class SpringOfAOPConfig {
  6. @Bean
  7. public MathCalculator mathCalculator () {
  8. return new MathCalculator();
  9. }
  10. @Bean
  11. public LogAspects logAspects () {
  12. return new LogAspects();
  13. }
  14. }

第五步,测试:

  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest
  3. public class DemoApplicationTests {
  4. @Test
  5. public void contextLoads() {
  6. //根据配置类获取SPring容器
  7. AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringOfAOPConfig.class);
  8. //从容器中获取Bean
  9. MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
  10. //执行除法运算
  11. mathCalculator.div(1, 1);
  12. //关闭容器
  13. applicationContext.close();
  14. }
  15. }

 

 

正常结果:

  1. 2018-12-11 11:01:25.496 INFO 16364 --- [ main] com.example.demo.DemoApplicationTests : Started DemoApplicationTests in 3.455 seconds (JVM running for 4.972)
  2. 环绕通知... 开始
  3. 除法运行...参数:{[1, 1]}
  4. MathCalculator.div...
  5. 环绕通知... 结束
  6. 除法结束...div
  7. 除法正常返回... 返回结果:{1}
  8. 2018-12-11 11:01:25.807 INFO 16364 --- [ Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'

异常结果:

  1. 2018-12-11 11:11:22.205 INFO 9628 --- [ main] com.example.demo.DemoApplicationTests : Started DemoApplicationTests in 3.532 seconds (JVM running for 4.559)
  2. 环绕通知... 开始
  3. 除法运行...参数:{[1, 0]}
  4. MathCalculator.div...
  5. 除法结束...div
  6. 异常... 异常信息:{java.lang.ArithmeticException: / by zero}
  7. java.lang.ArithmeticException: / by zero

看到没:

发生异常的时候@Around的方法执行后切入没有进行,但是@After的方法却执行了,所以原方法发生异常后顺序就是

1、@Around

2、@Brfore

3、原方法

4、@After

5、@AfterThrowing

 

https://blog.csdn.net/wangyijie521/article/details/84951558
posted on 2022-08-21 22:54  sunny123456  阅读(747)  评论(0编辑  收藏  举报