「Java筆記」 在Spring Boot中用註解快捷的使用AOP

「Java筆記」 在Spring Boot中用註解快捷的使用AOP

資源介紹參數
資源類別: Java
如遇問題: 聯繫客服/留言反饋
讓我們來面向切面編程吧,我們可以用AOP將某個共用的方法抽離出來,並在IOC容器中統一管理,而在Spring中是無法省略配置的,在Spring Boot中則完全不用,非常方便。下面以"記錄接口的訪問時長"功能場景來看看如何在 springboot 中使用 AOP。

 

讓我們來面向切面編程吧,我們可以用AOP將某個共用的方法抽離出來,並在IOC容器中統一管理,而在Spring中是無法省略配置的,在Spring Boot中則完全不用,非常方便。下面以”記錄接口的訪問時長”功能場景來看看如何在 springboot 中使用 AOP

添加 spring-boot 的 aop 依賴

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-aop</artifactId>
  4. </dependency>

編寫切面類和切面邏輯

  1. @Aspect
  2. @Component
  3. public class HttpRequestAspect {
  4. private static final Logger log = LoggerFactory.getLogger(HttpRequestAspect.class);
  5. public static long startTime;
  6. public static long endTime;
  7. /*@PointCut註解表示表示橫切點,哪些方法需要被橫切*/
  8. /*切點表達式*/
  9. @Pointcut("execution(public * com.simons.cn.springbootdemo.controller.*.*(..))")
  10. /*切點簽名*/
  11. public void print() {
  12. }
  13. /*@Before註解表示在具體的方法之前執行*/
  14. @Before("print()")
  15. public void before(JoinPoint joinPoint) {
  16. log.info("前置切面before……");
  17. startTime = System.currentTimeMillis();
  18. ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  19. HttpServletRequest request = requestAttributes.getRequest();
  20. String requestURI = request.getRequestURI();
  21. String remoteAddr = request.getRemoteAddr(); //這個方法取客戶端ip"不夠好"
  22. String requestMethod = request.getMethod();
  23. String declaringTypeName = joinPoint.getSignature().getDeclaringTypeName();
  24. String methodName = joinPoint.getSignature().getName();
  25. Object[] args = joinPoint.getArgs();
  26. log.info("請求url=" + requestURI + ",客戶端ip=" + remoteAddr + ",請求方式=" + requestMethod + ",請求的類名=" + declaringTypeName + ",方法名=" + methodName + ",入參=" + args);
  27. }
  28. /*@After註解表示在方法執行之後執行*/
  29. @After("print()")
  30. public void after() {
  31. endTime = System.currentTimeMillis() - startTime;
  32. log.info("後置切面after……");
  33. }
  34. /*@AfterReturning註解用於獲取方法的返回值*/
  35. @AfterReturning(pointcut = "print()", returning = "object")
  36. public void getAfterReturn(Object object) {
  37. log.info("本次接口耗時={}ms", endTime);
  38. log.info("afterReturning={}", object.toString());
  39. }
  40. }

1.可以看到我把@PointCut(×××)給單獨拎出來了,省的在@Before、@After、@AfterReturn 註解中重複寫,而是直接用類似於@Before(value=”print()”)代替,減少重複性代碼;

2.execution(public com.simons.cn.springbootdemo.controller..*(..)) 表示 com.simons.cn.springbootdemo.controller 包下的所有類中的所有方法,”..”表示所有方法中的參數不限個數;

編寫測試類測試下

  1. @GetMapping(value = "/index")
  2. @ResponseBody
  3. public String index() {
  4. ActivitySystemVariable systemVariable = activitySystemVariableMapper.selectByPrimaryKey(258);
  5. return systemVariable.toString();
  6. }

日誌輸出結果,ok

  1. 2018-06-28 11:21:10.939 INFO 10696 --- [nio-8888-exec-8] c.s.cn.springbootdemo.HttpRequestAspect : 前置切面before……
  2. 2018-06-28 11:21:10.939 INFO 10696 --- [nio-8888-exec-8] c.s.cn.springbootdemo.HttpRequestAspect : 請求url=/index,客戶端ip=0:0:0:0:0:0:0:1,請求方式=GET,請求的類名=com.simons.cn.springbootdemo.controller.IndexController,方法名=index,入參=[Ljava.lang.Object;@1efabee
  3. 2018-06-28 11:21:10.951 INFO 10696 --- [nio-8888-exec-8] c.s.cn.springbootdemo.HttpRequestAspect : 後置切面after……
  4. 2018-06-28 11:21:10.951 INFO 10696 --- [nio-8888-exec-8] c.s.cn.springbootdemo.HttpRequestAspect : 本次接口耗時=12ms
  5. 2018-06-28 11:21:10.951 INFO 10696 --- [nio-8888-exec-8] c.s.cn.springbootdemo.HttpRequestAspect : afterReturning=ActivitySystemVariable{id=258, name='simonsfan測試', svKey='simons-key', value='simons-value', memo='simonsfan測試', typeCode='', cataLog=0, createTime=2018-06-28 11:18:19.0}
聲明:本文為原創作品,版權歸作者所有。未經許可,不得轉載或用於任何商業用途。如若本站內容侵犯了原著者的合法權益,可聯繫我們進行處理。
2 條回復 A文章作者 M管理員
歡迎您,新朋友,感謝參與互動!
  1. ChenStr

    之前一直對AOP跟IOC一頭霧水現在終於了解一些了!