1. 程式人生 > 其它 >利用AOP切面列印專案中每個介面的執行情況

利用AOP切面列印專案中每個介面的執行情況

1、前言

AOP切面技術,大家應該都聽知道,Spring框架的主要功能之一。

AOP切面的用途很廣,其中一個常見的用途就是列印介面方法的執行日誌和執行時間。

日誌對於一個專案很是重要,不僅有助於調錯,還是後期大資料分析的重要資料來源,這裡我就簡單介紹一下如何在SpringBoot中利用AOP切面列印後端介面的執行情況。

2、切面程式碼

實現方式很簡單,在SpringBoot工程中,增加切面類,程式碼如下:

import cn.zhuifengren.util.JsonUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Aspect @Component @Order(Integer.MIN_VALUE) public class MyAspect { public static final Logger log = LoggerFactory.getLogger(MyAspect.
class); @Around("execution(* cn.zhuifengren.controller..*Controller.*(..))") public Object recordTimeLog(ProceedingJoinPoint joinPoint) throws Throwable { // 記錄開始時間 long begin = System.currentTimeMillis(); log.info("類資訊:{}", joinPoint.getTarget().getClass()); log.info("方法名:{}", joinPoint.getSignature().getName()); // 獲得request物件 RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); ServletRequestAttributes sra = (ServletRequestAttributes) requestAttributes; HttpServletRequest req = sra.getRequest(); log.info("請求地址: {}",req.getRequestURI()); log.info("請求裝置: {}", req.getHeader("user-agent")); // 獲得引數 Object[] args = joinPoint.getArgs(); if (args!=null && args.length>0){ for (int i = 0; i < args.length; i++) { if (args[i] instanceof HttpServletRequest || args[i] instanceof HttpServletResponse) continue; log.info("引數:" + ( args[i]==null? "": JsonUtils.objectToJson(args[i]))); } } // 執行目標 service Object result = joinPoint.proceed(); log.info("響應:" + JsonUtils.objectToJson(result)); // 記錄結束時間 long end = System.currentTimeMillis(); long time = end - begin; log.info("執行時間:{} 毫秒", time); return result; } }

3、程式碼說明

1)@Aspect 和@Component 兩個註解是切面類必須的,用於標識這是個切面類。

2)@Order(Integer.MIN_VALUE) 註解用於設定切面的執行順序,值越小,切面越早被執行。

3)@Around("execution(* cn.zhuifengren.controller..*Controller.*(..))")

眾所周知,AOP切面的通知方式有5種,方法執行前通知、方法正常執行後通知、環繞通知、方法執行異常通知、最終通知。

這裡的 @Around 就是環繞通知,也就是方法執行前後都會通知。

execution(* cn.zhuifengren.controller..*Controller.*(..)) 是切面表示式,用於指定哪些方法會被通知。

第一個 * 代表方法返回型別 *代表所有型別;

包名代表aop監控的類所在的包;

.. 代表該包以及其子包下的所有類方法;

*Controller代表類名,代表所有以Controller結尾的類,如果包括所有類,則直接寫 * ;

*(..) 中 *代表類中的方法名,(..)表示方法中的任何引數。

4)ProceedingJoinPoint joinPoint, 此物件是切面方法的引數,從中可以得到方法的請求引數,也用於執行方法得到響應值。

5)joinPoint.getArgs() 獲得引數。

6)Object result = joinPoint.proceed(),執行方法,並得到返回值

4、日誌效果