導入依賴
在pom文件中加入如下依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
LogAOP
創建一個日誌切面,用來記錄方法執行耗時
@Aspect
@Order(1)
@Configuration
public class LogAop {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
// 切點
private final static String POINTCUT_LOG_CONTROLLER = "execution (* com.frog.mybatisplus.controller.*.*(..))";
private final static String POINTCUT_LOG_SERVICE = "execution (* com.frog.mybatisplus.service.impl.*.*(..))";
private final static String POINTCUT_LOG = POINTCUT_LOG_CONTROLLER + " || " + POINTCUT_LOG_SERVICE;
// 環繞通知
@Around(POINTCUT_LOG)
public Object logAround(ProceedingJoinPoint joinPoint) {
// 獲取切點參數
Object[] args = joinPoint.getArgs();
// 獲取方法全限定名
String methodName = joinPoint.getSignature().getDeclaringTypeName();
// 打印執行前日誌
printBeforeLog(methodName, args);
// 執行時間起
long start = System.currentTimeMillis();
try {
// 執行方法
Object proceed = joinPoint.proceed();
// 執行時間止
long end = System.currentTimeMillis();
// 打印執行後日志
printAfterLog(methodName, args, proceed, end - start);
return proceed;
} catch (Throwable e) {
// 處理異常
printErrorLog(methodName, args, e);
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else {
throw new RuntimeException(e);
}
}
}
private void printErrorLog(String methodName, Object[] args, Throwable e) {
if (logger.isInfoEnabled()) {
logger.info("[{}] 方法執行異常,參數[{}],異常信息[{}]",
methodName,
argsToParamStr(args),
e);
}
}
private void printAfterLog(String methodName, Object[] args, Object proceed, long l) {
if (proceed == null) {
proceed = "null";
}
if (logger.isInfoEnabled()) {
logger.info("[{}] 方法執行成功,參數[{}],執行時間[{}ms],返回值[{}]",
methodName,
argsToParamStr(args),
l,
proceed);
}
}
private void printBeforeLog(String methodName, Object[] args) {
if (logger.isInfoEnabled()) {
logger.info("[{}] 方法請求成功,參數[{}]", methodName, argsToParamStr(args));
}
}
private String argsToParamStr(Object[] args) {
return Stream.of(args)
.map(o -> {
if (o == null) {
return "null";
}
if (o.getClass().isPrimitive()) {
// 基本類型輸出值
return o.toString();
} else {
// 不是基本類型
if (o.toString().length() > 100) {
return o.getClass().getName();
} else {
return o.toString();
}
}
})
.collect(Collectors.joining(", ", "{", "}"));
}
}
@Aspect註解表示這是一個切面
@Order(1)執行順序,數字越小越先進入切面
@Around環繞通知,相當於把執行方法包裹起來,也可以使用@Before+@AfterReturning+@AfterThrowing達到相同效果。