使用Spring Aop自定義註解實現自動記錄日誌
阿新 • • 發佈:2018-12-27
百度加自己琢磨,以下親測有效,所以寫下來記錄,也方便自己回顧瀏覽加深印象之類,有什麼問題可以評論一起解決,不完整之處也請大佬指正,一起進步哈哈
(1)首先配置檔案:
<!-- 宣告自動為spring容器中配置@aspectj切面的bean建立代理 ,織入切面 --> <aop:aspectj-autoproxy /> <!-- 開啟註解掃描 --> <context:component-scan base-package="com.ky.zhjd.**"/> <!-- 為true說明代理基於類被建立(預設false,基於介面被建立) --> <aop:config proxy-target-class="true"></aop:config>
(2)建立一個自定義註解類
注意建立時選Annotation,類名我叫ArchivesLog(日誌檔案的意思)。
ArchivesLog.java內容:
package com.ky.zhjd.common.log; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target; /** * * 自定義註解類 * @author ddz * */ @Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ArchivesLog { /** 要執行的操作型別比如:新增操作 **/ public String operationType() default ""; /** 要執行的操作名稱比如:新增一條使用者資料 **/ public String operationName() default ""; }
(3)新建一個切面類,我叫LogAspect.java
package com.ky.zhjd.common.log; import java.lang.reflect.Method; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; /** * 切面類 * * @author ddz * */ @Aspect @Component("logAspect") public class LogAspect { private static final Logger log = LoggerFactory.getLogger(LogAspect.class); // 配置織入點 @Pointcut("@annotation(ArchivesLog)") public void logPointCut() { } /** * 前置通知 用於攔截操作,在方法返回後執行 * * @param joinPoint 切點 */ @AfterReturning(pointcut = "logPointCut()") public void doBefore(JoinPoint joinPoint) { handleLog(joinPoint, null); } /** * 攔截異常操作,有異常時執行 * * @param joinPoint * @param e */ @AfterThrowing(value = "logPointCut()", throwing = "e") public void doAfter(JoinPoint joinPoint, Exception e) { handleLog(joinPoint, e); } private void handleLog(JoinPoint joinPoint, Exception e) { try { // 獲得註解 ArchivesLog controllerLog = getAnnotationLog(joinPoint); System.out.println("---------------自定義註解:" + controllerLog); if (controllerLog == null) { return; } // 獲得方法名稱 String className = joinPoint.getTarget().getClass().getName(); String methodName = joinPoint.getSignature().getName(); String type = controllerLog.operationType(); String name = controllerLog.operationName(); // 列印日誌 這裡可以進行插入資料庫操作 log.info(">>>>>>>>>>>>>操作型別:", type); log.info(">>>>>>>>>>>>>操作名稱:", name); log.info(">>>>>>>>>>>>>類名:", className); log.info(">>>>>>>>>>>>>方法名:", methodName); } catch (Exception exp) { // 記錄本地異常日誌 log.error("==前置通知異常=="); log.error("異常資訊:", exp.getMessage()); exp.printStackTrace(); } } /** * 是否存在註解,如果存在就獲取 */ private static ArchivesLog getAnnotationLog(JoinPoint joinPoint) throws Exception { Signature signature = joinPoint.getSignature(); MethodSignature methodSignature = (MethodSignature) signature; Method method = methodSignature.getMethod(); if (method != null) { // 拿到自定義註解中的資訊 return method.getAnnotation(ArchivesLog.class); } return null; } }
(4)在方法上使用註解 , 然後呼叫該方法
@ArchivesLog(operationType="查詢操作",operationName="查詢一條使用者詳情") @RequestMapping(value = "/findByid", produces={"application/json;charset=UTF-8"}) public @ResponseBody BaseResult<Object> findByid(String id) { String s="11"; BaseResult<Object> r=userService.findById(s); System.out.println(r+">>>>>>>>>>"); return r; }
ok 上效果:
有什麼不完善的地方歡迎指出,一起學習