美文网首页
SpringBoot 基于AOP的低侵入式日志

SpringBoot 基于AOP的低侵入式日志

作者: 97度的开水 | 来源:发表于2020-12-16 14:14 被阅读0次

​ 使用Springboot Aop 注解的方式 实现

1.声明日志注解

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemLog {
     String description() default "";
}

2.用于日志记录的 DO

public class SystemLogDO {
    /** id*/
    private String id;

    /** 操作用户id*/
    private Long userId;

    /** 类名*/
    private String clazz;

    /** 方法名*/
    private String method;

    /** 描述*/
    private String description;

    /** 操作时间*/
    private Date operateTime;

    /** 操作ip*/
    private String ip;

    /** 请求参数*/
    private String args;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id == null ? null : id.trim();
    }

    public Long getUserId() {
        return userId;
    }

    public void setUserId(Long userId) {
        this.userId = userId;
    }

    public String getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz == null ? null : clazz.trim();
    }

    public String getMethod() {
        return method;
    }

    public void setMethod(String method) {
        this.method = method == null ? null : method.trim();
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description == null ? null : description.trim();
    }

    public Date getOperateTime() {
        return operateTime;
    }

    public void setOperateTime(Date operateTime) {
        this.operateTime = operateTime;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip == null ? null : ip.trim();
    }

    public String getArgs() {
        return args;
    }

    public void setArgs(String args) {
        this.args = args == null ? null : args.trim();
    }
}

3.记录日志

@Aspect
@Component
@SuppressWarnings("all")
public class SystemLogAspect {
    private static final Logger logger = LoggerFactory.getLogger(ResourceFilterAspect.class);


    @Autowired
    private SystemLogService systemLogService;//日志服务方法

    @Autowired
    private ObjectMapper objectMapper;//序列化成JSON的工具


    private Class[] ignoreClasses = {HttpServletRequest.class, HttpServletResponse.class};//需要忽略的类
    private String[] ignoreParams = {};//需要忽略的参数

    @Pointcut("@annotation(com.jandar.portal.annotation.SystemLog)")
    public void logsAspect() {//注解切点
        System.out.println("log");
    }

    @Around("logsAspect()")
    public Object logRecording(ProceedingJoinPoint pjp) throws Throwable {
        try {
            //获取方法签名
            MethodSignature signature = (MethodSignature) pjp.getSignature();
            Method method = signature.getMethod();
            SystemLog log = method.getAnnotation(SystemLog.class);
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String ip = IPUtil.getRealIP(request);//获取ip
            Map<String, Object> argMap = toArgsMap(pjp.getArgs(), signature, ignoreClasses, ignoreParams);//获取参数
            Date operateTime = new Date();
            String description = log.description();//获取注解中的描述
            String clazzName = pjp.getTarget().getClass().getTypeName();
            String methodName = pjp.getSignature().getName();
            //记录日志
            SystemLogDO systemLogDO = new SystemLogDO();
            systemLogDO.setIp(ip);
            systemLogDO.setDescription(description);
            systemLogDO.setClazz(clazzName);
            systemLogDO.setMethod(methodName);
            systemLogDO.setOperateTime(operateTime);
            systemLogDO.setUserId(CurrentUserUtil.MANAGER_USER_ID());
            try {
                systemLogDO.setArgs(objectMapper.writeValueAsString(argMap));
            } catch (Exception e) {
                logger.error("Arg属性异常");
            }

            systemLogService.add(systemLogDO);//保存日志
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
        return pjp.proceed();
    }


    /**
     * 提取有效参数
     *
     * @param args
     * @param methodSignature
     * @param ignoreClasses
     * @param ignoreParams
     * @return
     */
    protected Map<String, Object> toArgsMap(Object[] args, MethodSignature methodSignature,
                                            Class<?>[] ignoreClasses, String[] ignoreParams) {
        Map<String, Object> paramMap = Maps.newHashMap();
        for (int i = 0; i < methodSignature.getParameterNames().length; i++) {
            String paramName = methodSignature.getParameterNames()[i];
            if (!isIgnoreParamType(args[i], ignoreClasses)
                    && !isIgnoreParam(paramName, ignoreParams)) {
                paramMap.put(paramName, args[i]);
            }
        }
        return paramMap;
    }

    /**
     * 忽略参数类型
     *
     * @param param
     * @param classes
     * @return
     */
    protected boolean isIgnoreParamType(Object param, Class<?>[] classes) {
        for (Class<?> aClass : classes) {
            if (aClass.isInstance(param)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 忽略参数
     *
     * @param name
     * @param paramNames
     * @return
     */
    protected boolean isIgnoreParam(String name, String[] paramNames) {
        for (String paramName : paramNames) {
            if (name.equals(paramName)) {
                return true;
            }
        }
        return false;
    }

相关文章

  • SpringBoot 基于AOP的低侵入式日志

    ​ 使用Springboot Aop 注解的方式 实现 1.声明日志注解 2.用于日志记录的 DO 3.记录日志

  • 从redis到分布式架构,通过Redis学AKF划分原则、CAP

    基于SpringBoot AOP面向切面编程实现Redis分布式锁基于SpringBoot AOP面向切面编程实现...

  • 基于SpringBoot AOP面向切面编程实现Redis分布式

    基于SpringBoot AOP面向切面编程实现Redis分布式锁基于SpringBoot AOP面向切面编程实现...

  • AOP

    相关依赖 java动态代理 注解aop(侵入式) 非侵入式 XML配置

  • SpringBoot AOP处理请求日志处理打印

    SpringBoot AOP处理请求日志处理打印 赵小胖个人博客

  • 01. struts2介绍

    struts2优点 与Servlet API 耦合性低。无侵入式设计 提供了拦截器,利用拦截器可以进行AOP编程,...

  • SpringBoot-AOP

    SpringBoot-AOP 使用AOP统一处理请求日志 1.AOP的概念 AOP:AOP是一种编程范式,与语言无...

  • face_spring

    spring简介以及优点好处 spring是一个非侵入式低耦合的一个框架,IOC控制管理bean,AOP增强bea...

  • 事务的两种形式

    事务的分类 编程式事务:是指在代码中手动的管理事务,缺点:代码侵入性太强 声明式事务:基于AOP面向切面,将业务与...

  • Spring

    1、Spring优点: 低侵入式的设计,代码污染度低; 独立于各种应用服务器,基于Spring框架的应用真正实现了...

网友评论

      本文标题:SpringBoot 基于AOP的低侵入式日志

      本文链接:https://www.haomeiwen.com/subject/nvvigktx.html