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参数的值



个人总结 如果不正确或者不理解之处欢迎留言指出


 
posted @ 2018-04-13 14:51  dream_on_sakura_rain  阅读(2256)  评论(1编辑  收藏  举报