AOP實現日志收集和記錄


springboot項目中使用注解的方式實現

 

首先:編寫一個對於操作方法進行日志記錄的注解

package com.springtest.annotation;


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogAnnonation {

/**
* 操作類型,方便記錄
* @return String
*/
String value() default "";
}

然后,注解的切面配置

 這里采用了兩中切面通知:
  分別是返回通知和異常通知,注解中的參數方便在返回通知或者異常通知中處理操作類型(方法做了什么操作)

  返回通知是方法正常執行時候會進入的通知方法,可以通過對方法返回值的信息判斷方法執行結果是或否成功
  異常通知是方法執行產生異常進入的方法

@Aspect
@Component
public class LogInterceptor {

    private static final Logger LOGGER = LoggerFactory.getLogger(OperationLogInterceptor.class);

    /**
     * 定義切入點為 帶有 LogAnnonation 注解的
     */
    @Pointcut("@annotation(com.trendytech.tapp.annotation.LogAnnonation)")
    private void param() {
    }


    /**
     * 返回通知(正常返回)
     */
    @AfterReturning(value = "param()", returning = "result")
    public void afterReturning(JoinPoint joinPoint, ResponseData result) throws Throwable {
        String operationResult = "失敗";
        if (result.getCode() == ResponseCode.SUCCESS) {
            operationResult = "成功";
        }
        dealDifferentLogs(joinPoint, operationResult);
    }

    /**
     * 異常通知(失敗操作)
     */
    @AfterThrowing(value = "param()", throwing = "exception")
    public void afterThrowing(JoinPoint joinPoint, Exception exception) throws Throwable {
        dealDifferentLogs(joinPoint, "失敗");
        LOGGER.error("OperationLogInterceptor afterThrowing exception catch ...", exception);
    }
    


}

 

如何使用

 

舉個栗子:

只需要在操作的方法上面加上方法的注解和注解攜帶的參數值即可

 @OperationLog("MODIFY_VIRTUAL")
    @RequestMapping(value = "/{id}", method = RequestMethod.PUT)
    public ResponseData<VirtualVo> modifyVirtualServer(@PathVariable("id") String id,
                    @RequestBody VirtualVo virtualServer) {
        return virtualServerService.modify(id, virtualServer);
    }

 

備注:使用這種方式手機日志還需要支持一個方法,從注解中取得注解value從而判斷這個方法的操作類型是什么,方法如下

獲取注解定義的參數----就是上面代碼中的

@OperationLog("MODIFY_VIRTUAL")

/**
     * 獲取自定義注解的參數
     *
     * @param joinPoint joinPoint
     * @return LogAnnotation 注解
     * @throws ClassNotFoundException ClassNotFoundException
     */
    public LogAnnotation getAnnotationParam(JoinPoint joinPoint) throws ClassNotFoundException {
        String targetName = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        Class targetClass = Class.forName(targetName);
        Method[] methods = targetClass.getMethods();
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                return method.getAnnotation(OperationLog.class);
            }
        }
        return null;
    }

 

 

獲取注解方法中某個參數的值

 

 /**
     * 通過反射機制 獲取被切參數名以及參數值
     *
     * @param joinPoint joinPoint
     * @return 參數集合
     * @throws NotFoundException      NotFoundException
     * @throws ClassNotFoundException ClassNotFoundException
     */
    public static Map<String, Object> getMethodParams(JoinPoint joinPoint)
                    throws NotFoundException, ClassNotFoundException {
        //參數名稱
        String[] paramName = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
        //參數值
        Object[] paramValue = joinPoint.getArgs();
        Map<String, Object> map = new HashMap<>();
        for (int i = 0; i < paramName.length; i++) {
            try {
                map.put(paramName[i], paramValue[i]);
            } catch (Exception e) {
                LOGGER.error("get method params error!", e);
            }
        }
        return map;
    }

備注:使用方法為

getMethodParams(joinPoint).get(id);  獲取方法中的id參數的值



個人總結 如果不正確或者不理解之處歡迎留言指出


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM