• SpringBoot应用AOP及各注解的执行顺序 统一AOP切面


    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
  • 相关阅读:
    单例模式
    EasyExcel的基本使用方法
    交换两个整数,要求不能用一二则运算表达式,不得使用中间变量
    IDEA的基本使用技巧
    分区表常用操作汇总
    Orion测试磁盘性能
    samba安装和简单配置使用
    oracle批量处理范例
    Oracle中绑定变量的使用
    不修改sql文本情況下,改變其執行計劃
  • 原文地址:https://www.cnblogs.com/sunny3158/p/16611321.html
Copyright © 2020-2023  润新知