SpringBoot使用自定義註解結合AOP完成日誌收集

一、創建一個自定義註解

     註解中包含了模塊的名稱以及具體操作,可以根據自己的需求進行修改或者擴展。

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

    /**
     * 模塊名稱
     */
    String module();

    /**
     * 具體操作
     */
    String operate();

    /**
     * 備註
     */
    String remarks() default "";
}

二、創建切面類

@Aspect
@Component("com.*")
@Slf4j
public class OperationLogAspect {

    @Autowired
    private SysLogService sysLogService;

    // 配置切入點(以OperationLog註解爲標誌)
    @Pointcut("@annotation(com.app.appweb.anno.OperationLogAnnotation)")
    public void logPointCut() {

    }

    /**
     * 後置通知 用於攔截操作,在方法返回後執行
     *
     * @param joinPoint 切點
     */
    @AfterReturning(pointcut = "logPointCut()")
    public void doAfter(JoinPoint joinPoint) {
        handleLog(joinPoint, null);
    }

    /**
     * 攔截異常操作,有異常時執行
     */
    @AfterThrowing(value = "logPointCut()", throwing = "e")
    public void doAfter(JoinPoint joinPoint, Exception e) {
        handleLog(joinPoint, e);
    }

    private void handleLog(JoinPoint joinPoint, Exception e) {
        try {
            // 獲得註解
            OperationLogAnnotation controllerLog = getAnnotationLog(joinPoint);
            if (controllerLog == null) {
                return;
            }
            // 模塊詳情
            Object module = controllerLog.module();
            // 具體操作
            Object operate = controllerLog.operate();
            // 訪問類名
            String className = joinPoint.getTarget().getClass().getName();
            // 訪問方法名
            String methodName = joinPoint.getSignature().getName();
            //參數
            Object[] params = joinPoint.getArgs();
            String param = "";

            for (int i = 0; i < params.length; i++) {
                param = param + "," + params[i] + "";
            }
            //RequestContextHolder:持有上下文的Request容器,獲取到當前請求的request
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest();
            //獲取請求URL
            String path = httpServletRequest.getRequestURI();
           
            // 保存日誌
            SysLog sysLog = new SysLog();
            sysLog.setOperation(operate.toString());
            sysLog.setMethod(methodName);
            sysLog.setPath(path);
            sysLog.setParam(param);
            sysLogService.insert(sysLog);
             //保存日誌完成
        } catch (Exception ex) {
            // 異常日誌輸出
            log.error("異常信息:{}", ex.getMessage());
            ex.printStackTrace();
        }
    }

    /**
     * @Description 判斷方法是否存在註解,如果存在註解則返回註解對象
     * @Date 2019/7/26 11:27
     * @Param [joinPoint]
     * @Exception
     */
    private OperationLogAnnotation getAnnotationLog(JoinPoint joinPoint) throws Exception {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();
        if (method != null) {
            return method.getAnnotation(OperationLogAnnotation.class);
        }
        return null;
    }

}

三、在控制器的controller方法添加註解

@OperationLogAnnotation(module = "設置模塊", operate = "新增系統用戶")

將以上註解添加到用戶新增的controller方法上即可。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章