经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring Boot » 查看文章
Springboot整合AOP和注解,实现丰富的切面功能
来源:cnblogs  作者:南瓜慢说  时间:2023/2/10 9:23:29  对本文有异议

简介

我们在文章《Spring AOP与AspectJ的对比及应用》介绍了AOP的使用,这篇文章讲解一下AOP与注解的整合,通过注解来使用AOP,会非常方便。为了简便,我们还是来实现一个计时的功能。

整合过程

首先创建一个注解:

  1. @Retention(RetentionPolicy.RUNTIME)
  2. @Target(ElementType.METHOD)
  3. public @interface PkslowLogTime {
  4. }

然后在一个Service中使用注解:

  1. @Service
  2. @Slf4j
  3. public class TestService {
  4. @PkslowLogTime
  5. public void fetchData() {
  6. log.info("fetchData");
  7. try {
  8. Thread.sleep(500);
  9. } catch (InterruptedException e) {
  10. throw new RuntimeException(e);
  11. }
  12. }
  13. }

这个Service的方法会在Controller中调用:

  1. @GetMapping("/hello")
  2. public String hello() {
  3. log.info("------hello() start---");
  4. test();
  5. staticTest();
  6. testService.fetchData();
  7. log.info("------hello() end---");
  8. return "Hello, pkslow.";
  9. }

接着是关键一步,我们要实现切面,来找到注解并实现对应功能:

  1. @Aspect
  2. @Component
  3. @Slf4j
  4. public class PkslowLogTimeAspect {
  5. @Around("@annotation(com.pkslow.springboot.aop.PkslowLogTime) && execution(* *(..))")
  6. public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
  7. log.info("------PkslowLogTime doAround start------");
  8. MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
  9. // Get intercepted method details
  10. String className = methodSignature.getDeclaringType().getSimpleName();
  11. String methodName = methodSignature.getName();
  12. // Measure method execution time
  13. StopWatch stopWatch = new StopWatch(className + "->" + methodName);
  14. stopWatch.start(methodName);
  15. Object result = joinPoint.proceed();
  16. stopWatch.stop();
  17. // Log method execution time
  18. log.info(stopWatch.prettyPrint());
  19. log.info("------PkslowLogTime doAround end------");
  20. return result;
  21. }
  22. }

@Around("@annotation(com.pkslow.springboot.aop.PkslowLogTime) && execution(* *(..))")这个表达式很关键,如果不对,将无法正确识别;还有可能出现多次调用的情况。多次调用的情况可以参考:Stackoverflow

这里使用了Spring的StopWatch来计时。

测试

通过maven build包:

  1. $ mvn clean package

日志可以看到有对应的织入信息:

  1. [INFO] Join point 'method-execution(java.lang.String com.pkslow.springboot.controller.TestController.hello())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:22) advised by around advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))
  2. [INFO] Join point 'method-execution(java.lang.String com.pkslow.springboot.controller.TestController.hello())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:22) advised by before advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))
  3. [INFO] Join point 'method-execution(void com.pkslow.springboot.controller.TestController.test())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:31) advised by around advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))
  4. [INFO] Join point 'method-execution(void com.pkslow.springboot.controller.TestController.test())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:31) advised by before advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))
  5. [INFO] Join point 'method-execution(void com.pkslow.springboot.controller.TestController.staticTest())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:37) advised by around advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))
  6. [INFO] Join point 'method-execution(void com.pkslow.springboot.controller.TestController.staticTest())' in Type 'com.pkslow.springboot.controller.TestController' (TestController.java:37) advised by before advice from 'com.pkslow.springboot.aop.ControllerAspect' (ControllerAspect.class(from ControllerAspect.java))
  7. [INFO] Join point 'method-execution(void com.pkslow.springboot.service.TestService.fetchData())' in Type 'com.pkslow.springboot.service.TestService' (TestService.java:12) advised by around advice from 'com.pkslow.springboot.aop.PkslowLogTimeAspect' (PkslowLogTimeAspect.class(from PkslowLogTimeAspect.java))

启动应用后访问接口,日志如下:

总结

通过注解可以实现很多功能,也非常方便。而且注解还可以添加参数,组合使用更完美了。

代码请看GitHub: https://github.com/LarryDpk/pkslow-samples

原文链接:https://www.cnblogs.com/larrydpk/p/17100953.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号