AOP操作日志方案设计

AOP操作日志方案设计
1.添加maven依赖
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2. 操作日志注解类
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface OperateLog {

    /**
     * 操作类型
     * @return 操作类型枚举
     */
    OperateTypeEnum operateType() default OperateTypeEnum.OTHER;

    /**
     * 操作描述
     * @return 字符串
     */
    String operateDesc() default " ";
}
3. 操作类型枚举类
public enum OperateTypeEnum {
    LOGIN, LOGOUT, OFFLINE, ONLINE, OTHER;
}
4. 切面类记录操作日志
@Aspect
@Component
public class OperateLogAspect {

    /**
     * 设置操作日志切入点,记录操作日志,在注解的位置切入代码
     */
    @Pointcut("@annotation(OperateLog)")
    public void operateLogPointCut() {
    }

    /**
     * 正常返回通知,拦截用户操作日志,连接点正常执行完成后执行,如果连接点抛出异常,则不执行
     * @param joinPoint 切入点
     * @param keys 返回结果
     */
    @AfterReturning(value = "operateLogPointCut()", returning = "keys")
    public void saveOperateLog(JoinPoint joinPoint, Object keys) {
        // 获取RequestAttributes
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        // 获取HttpServletRequest
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);

        try {
            // 从切面织入点处通过反射机制获取织入点处的方法
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            // 获取切入点所在的方法
            Method method = signature.getMethod();
            // 获取操作
            OperateLog operateLog = method.getAnnotation(OperateLog.class);
            if (!Objects.isNull(operateLog)) {
                String operateType = operateLog.operateType().name();
                System.out.println("operateType = " + operateType);
            }
            // 获取请求类的类名
            String className = joinPoint.getTarget().getClass().getName();
            // 获取请求的方法名
            String methodName = method.getName();
            methodName = className + "." + methodName;
            // 获取请求参数
            String params = JSON.toJSONString(parsingParam(joinPoint, signature, method));
            // 返回处理结果
            String returnResultParam = JSON.toJSONString(keys);
            System.out.println("request param : " + params + ", return result param : " + returnResultParam);
          	// TODO 将日志信息保存到日志表中
        } catch (Exception e) {
          e.printStackTrace();
        }
    }

    /**
     * 解析参数列表
     * @param joinPoint
     * @param signature
     * @param method
     * @return
     */
    private Map<String, Object> parsingParam(JoinPoint joinPoint, MethodSignature signature, Method method) {
        Object[] args = joinPoint.getArgs();
        ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
        String[] parameterNames = parameterNameDiscoverer.getParameterNames(method);
        Map<String, Object> paramMap = new HashMap<>(32);
        if (!Objects.isNull(parameterNames)) {
            for (int i = 0; i < parameterNames.length; i++) {
                paramMap.put(parameterNames[i], args[i]);
            }
        }
        return paramMap;
    }
}

版权声明:本文为zhangenping0234原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。