1. 程式人生 > 實用技巧 >Aop示例之註解切面方式實現日誌列印

Aop示例之註解切面方式實現日誌列印

在使用切面前,首先保證專案配置啟動對@AspectJ註解的支援及監聽類,在Spring的配置檔案中,新增如下配置即可:

<!-- 啟動對@AspectJ註解的支援  -->
<aop:aspectj-autoproxy proxy-target-class="true" />

示例:

import com.credithc.channel.common.util.JsonUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; import java.util.Arrays; /** * 針對base服務模組api的日誌列印切面 * * @author kuangxiang * @date 2020/9/16 10:55 */ @Aspect @Component public class LogAspectForBaseApi {
private Logger logger = LoggerFactory.getLogger(this.getClass()); /** * 定義切點 * <p> * 作用是供通知方法知道需要在何處執行通知 * execution:可以是個包路徑,例如本示例中;也可以是自定義的註解 * </P> */ @Pointcut("execution(* com.credithc.channel.base.service.api.*.*(..))") public void point() { }
/** * 環繞通知 * <p> * 1.在目標方法執行前和執行後都會執行此方法 * 2.介面中的引數對應ProceedingJoinPoint而不是JoinPoint,是因為 ProceedingJoinPoint繼承了JoinPoint是在JoinPoint的基礎上暴露出proceed 這個方法 , * 執行proceed方法的作用是讓目標方法執行,這也是環繞通知和前置、後置通知方法的一個最大區別。 * </P> * * @param proceedingJoinPoint * @return * @throws Throwable */ @Around("point()") public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { String className = proceedingJoinPoint.getTarget().getClass().getName(); MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature(); String methodName = signature.getName(); Object[] args = proceedingJoinPoint.getArgs(); logger.info("請求【{}.{}】開始,req:{}", className, methodName, Arrays.toString(args)); long beginTime = System.currentTimeMillis(); // 執行方法 Object result = proceedingJoinPoint.proceed(); // 執行時長(毫秒) long costTime = System.currentTimeMillis() - beginTime; logger.info("請求【{}.{}】結束,req:{},result:{},執行時間:【{}】毫秒", className, methodName, Arrays.toString(args), JsonUtil.toJson(result), costTime); return result; } /** * 目標方法執行前執行 * * @param joinPoint 切點物件 */ @Before("point()") public void before(JoinPoint joinPoint) { } /** * 目標方法正常結束後執行 * * @param joinPoint 切點物件 * @param resp 這個引數定義目標方法響應結果引數名,和@AfterReturning註解中returening屬性的值是一致的 */ @AfterReturning(returning = "resp", pointcut = "point()") public void afterReturn(JoinPoint joinPoint, Object resp) { } /** * 目標方法非正常結束時列印 * * @param throwable 異常資訊,此引數是方法執行中丟擲的異常資訊,和@AfterThrowing註解中throwing屬性的值是一致的 */ @AfterThrowing(value = "point()", throwing = "throwable") public void afterThrowing(Throwable throwable) { } }