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



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


     
  • 相关阅读:
    redis基础配置
    brew安装mysql
    iptables 执行清除命令 iptables -F 要非常小心
    nginx反向代理部署nodejs配置
    Starting MySQL... ERROR! The server quit without updating PID file 问题解决
    iframe自适应高度问题
    js正则常用的一些东西
    node.js批量重命名文件
    [转]MySQL5字符集支持及编码研究
    PHP $_SERVER的使用
  • 原文地址:https://www.cnblogs.com/licunzhi/p/8673151.html
Copyright © 2020-2023  润新知