註解+Aspect 省時省力的管理好接口日誌

背景

無論是對外提供的RPC接口,還是項目內的普通方法,我們都會有需要打印方法入參、出參的需求,方便在遇到問題時通過查看日誌快速定位,我們也會需要對方法的執行時間進行打印 方便分析和調優。
比較笨的做法就是在每個需要打印日誌的地方使用log.info對參數進行打印,在每個方法內部方法體前後獲取系統時間 在最後打印時間差
但這種對方法自身業務邏輯沒有什麼意義的的代碼 侵入性太強 編寫時也浪費時間 所以我們可以通過註解+AOP的方法 對這些操作進行封裝 基於註解的控制又方便隨時隨地的使用

怎麼做

定義註解

package com.common.interceptor.annotation;

import java.lang.annotation.*;

/**
 * 方法執行的入參 出參 及 執行時間
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RunTimeAnnotation {
}

Aspect

我們使用Aspect進行切面開發
首先引用對應的pom依賴

 <dependency>
    <groupId>org.aspectj</groupId>
     <artifactId>aspectjweaver</artifactId>
     <version>1.7.3</version>
 </dependency>

定義切面類:
這裏使用@Around定義環繞通知

package com.common.interceptor;
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;

@Aspect
@Component
public class RunTimeAspect {
    private static final Logger logger = LoggerFactory.getLogger(RunTimeAspect.class);

    @Around("@annotation(com.common.interceptor.annotation.RunTimeAnnotation)")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
        long startTime = System.currentTimeMillis();
        //接收到請求,記錄請求內容
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //獲取參數
        Object[] args = joinPoint.getArgs();
        //獲取方法
        String methodName = signature.getDeclaringTypeName() + "." + signature.getName();
        Object obj = null;
        try {
            logger.info("{}方法執開始執行,入參{}",methodName,args);
            obj = joinPoint.proceed();
            long excuteTime = System.currentTimeMillis() - startTime;
            logger.info("{}方法執結束執行,耗時{}ms,入參{},返回值{}",methodName,excuteTime,args,obj);
        } catch (Exception throwable) {
            logger.error("{}方法執行異常{}",methodName,throwable);
            //異常要拋出去 否則會影響外部方法事務回滾
            throw throwable;
        }
        return obj;
    }
}

寫好後,我們只需要在需要的地方加上@RunTimeAnnotation 註解就可以了

@RunTimeAnnotation
public void consumer(String message){
         //...
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章