在開發中,咱們可能須要記錄異常日誌。因爲異常比較分散,每一個 service 方法均可能發生異常,若是咱們都去作處理,會出現不少重複編碼,也很差維護。這種場景就應該想到 aop, aop 的出現就是爲了解決這類問題。java
咱們能夠自定義一個註解,在須要記錄的日誌的方法上面打這個註解。 而後使用 aop ,去切 service 層的方法,判斷方法上有沒有這個註解,若是有就進行日誌處理。spring
定義註解:數據庫
package com.jerryl.auth.service.aop.log; import java.lang.annotation.*; /** \* created by Demon, on 2018/7/22 */ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface RecordLog { String comment() default ""; }
使用 aspect 作切面編碼
package com.jerryl.auth.service.aop.log; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import org.springframework.util.StopWatch; import java.lang.reflect.Method; /** \* created by Demon, on 2018/7/22 */ @Aspect @Component public class RecordLogAspect { @Pointcut("execution(public * com.jerryl.auth.service..\*Manager.\*(..))") public void addLog() {} @Around("addLog()") public Object addLog(ProceedingJoinPoint joinPoint) { StopWatch stopWatch = new StopWatch(); stopWatch.start(); // 取類全名 String typeName = joinPoint.getSignature().getDeclaringTypeName(); // 取方法名 String methodName = joinPoint.getSignature().getName(); // 判斷方法是否是有日誌註解 MethodSignature joinPointObject = (MethodSignature) joinPoint.getSignature(); Method method = joinPointObject.getMethod(); boolean hasRecordLogAnnotation = method.isAnnotationPresent(RecordLog.class); Object result = null; try { if (hasRecordLogAnnotation) { result = joinPoint.proceed(); stopWatch.stop(); // 方法執行時間 long totalTimes = stopWatch.getTotalTimeMillis(); } } catch (Throwable throwable) { // 保存方法名,執行時間,異常信息到數據庫表,記錄 error 日誌,方法返回 } // 記錄操做成功的正常日誌 return result; } }
若是系統某些操做只有超級管理員的需求,也能夠經過 註解加前置通知的方法解決!spa