aop + annotation 實現統一日誌記錄

aop + annotation 實現統一日誌記錄

在開發中,咱們可能須要記錄異常日誌。因爲異常比較分散,每一個 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

相關文章
相關標籤/搜索