• 【最详细实战】实战项目添加操作日志(aop、注解实现)


    1、先定义aop

    package cn.com.taiji.lawenforcement.logger.aop;
    
    import cn.com.taiji.lawenforcement.core.config.UserInfoContext;
    import cn.com.taiji.lawenforcement.logger.entity.OperationLog;
    import cn.com.taiji.lawenforcement.logger.service.IOperationLogService;
    import lombok.extern.slf4j.Slf4j;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import javax.servlet.http.HttpServletRequest;
    import java.lang.reflect.Method;
    import java.time.LocalDateTime;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * 日志切面
     */
    
    @Aspect
    @Component
    @Slf4j
    @MapperScan("cn.com.taiji.lawenforcement.logger.mapper")
    public class OperationLogAspect {
    
        private ThreadLocal operationLogThreadLocal = new ThreadLocal<>();
    
        @Autowired
        IOperationLogService logService;
    
        /**
         * 前置通知,方法调用前触发 -记录开始时间
         */
    
        @Before("@annotation(cn.com.taiji.lawenforcement.logger.annotation.OperationLog)")
        public void beforeAdvice(JoinPoint joinPoint) {
            // 记录方法开始执行的时间
            // 接收到请求,记录请求内容
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
                    .getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
    
            Map descMap = new HashMap<>();
            try {
                descMap = getControllerMethodDescription(joinPoint);
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            //获取当前登录人信息
            UserInfoContext.UserInfo userInfo = UserInfoContext.currentUserInfo();
            OperationLog operationLog = OperationLog.builder()
                    .startTime(String.valueOf(System.currentTimeMillis()))
                    .clientIp(request.getRemoteAddr())
                    .deptId((null!=userInfo)?userInfo.getDeptId():"")
                    .orgId((null!=userInfo)?userInfo.getOrgId():"")
                    .userId((null!=userInfo)?userInfo.getUserId():"")
                    .requestUri(request.getRequestURI())
                    .logDesc(descMap.get("desc"))
                    .logModule(descMap.get("module"))
                    .logOperationType(descMap.get("operationType"))
                    .build();
            operationLogThreadLocal.set(operationLog);
        }
    
        /**
         * 后置通知,在目标方法完成之后调用通知,此时不会关 心方法的输出是什么
         */
        @After("@annotation(cn.com.taiji.lawenforcement.logger.annotation.OperationLog)")
        public void afterAdvice(JoinPoint joinPoint) {
    
            OperationLog operationLog = operationLogThreadLocal.get();
            operationLog.setEndTime(String.valueOf(System.currentTimeMillis()));
            operationLog.setOperationTime(LocalDateTime.now());
            logService.save(operationLog);
    
        }
    
        private static Map getControllerMethodDescription(JoinPoint joinPoint) throws Exception {
            String targetName = joinPoint.getTarget().getClass().getName();
            String methodName = joinPoint.getSignature().getName();
            Object[] arguments = joinPoint.getArgs();
            Class targetClass = Class.forName(targetName);
            Method[] methods = targetClass.getMethods();
            Map temp = new HashMap<>();
            for (Method method : methods) {
                if (method.getName().equals(methodName)) {
                    Class[] clazzs = method.getParameterTypes();
                    if (clazzs.length == arguments.length) {
                        if (method.getAnnotation(cn.com.taiji.lawenforcement.logger.annotation.OperationLog.class) != null) {
                            temp.put("module", method.getAnnotation(cn.com.taiji.lawenforcement.logger.annotation.OperationLog.class).module());
                            temp.put("operationType",
                                    method.getAnnotation(cn.com.taiji.lawenforcement.logger.annotation.OperationLog.class).operationType());
                            temp.put("desc", method.getAnnotation(cn.com.taiji.lawenforcement.logger.annotation.OperationLog.class).desc());
                            break;
                        }
    
                    }
                }
            }
            return temp;
        }
    }
    

    2、定义注解

    package cn.com.taiji.lawenforcement.logger.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ ElementType.METHOD})
    public @interface OperationLog {
    
        // 模块名称
        String module() default "";
    
    
        // 日志操作类型
        String  operationType() default "";
    
        // 描述信息
        String desc() default "";
    }
    

    3、日志操作类型

    package cn.com.taiji.lawenforcement.logger.annotation;
    
    public interface OperationType {
    
        public static String ADD = "add";
        public static String DELETE ="delete";
        public static String EDIT ="edit";
        public static String QUERY = "query";
        public static String LOGINOUT ="loginOut";
        public static String LOGININ ="loginIn";
        public static String UPLOAD ="upload";
        public static String DOWNLOAD ="download";
        public static String IMPORT ="import";
        public static String EXPORT ="export";
    }
    

    4、实体类

    package cn.com.taiji.lawenforcement.logger.entity;
    
    import com.baomidou.mybatisplus.annotation.IdType;
    import com.baomidou.mybatisplus.annotation.TableField;
    import com.baomidou.mybatisplus.annotation.TableId;
    import com.baomidou.mybatisplus.annotation.TableName;
    import lombok.*;
    import lombok.experimental.Accessors;
    
    import java.io.Serializable;
    import java.time.LocalDateTime;
    
    
    @Data
    @EqualsAndHashCode(callSuper = false)
    @Accessors(chain = true)
    @TableName("tj_operation_log")
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public class OperationLog implements Serializable
    {
        
        private static final long serialVersionUID = 1L;
        
        @TableId(value = "id", type = IdType.AUTO)
        private Long id;
        
        /**
         * 用户id
         */
        @TableField("user_id")
        private String userId;
        
        /**
         * 部门id
         */
        @TableField("dept_id")
        private String deptId;
        
        /**
         * 用户姓名
         */
        @TableField("user_name")
        private String userName;
        
        /**
         * 局级id
         */
        @TableField("org_id")
        private String orgId;
        
        /**
         * 调用开始时间
         */
        @TableField("start_time")
        private String startTime;
        
        /**
         * 调用结束时间
         */
        @TableField("end_time")
        private String endTime;
        
        /**
         * 操作描述
         */
        @TableField("log_desc")
        private String logDesc;
        
        /**
         * 操作模块
         */
        @TableField("log_module")
        private String logModule;
        
        /**
         * 操作类型
         */
        @TableField("log_operation_type")
        private String logOperationType;
        
        /**
         * 请求路径
         */
        @TableField("request_uri")
        private String requestUri;
        
        /**
         * 客户端ip
         */
        @TableField("client_ip")
        private String clientIp;
        
        /**
         * 操作时间
         */
        @TableField("operation_time")
        private LocalDateTime operationTime;
        
        /**
         * 备注
         */
        @TableField("remark")
        private String remark;
        
    }
    

    5、log4j2配置文件

    在我的资源下载

    6、在依赖里,排除logging

    
        
            org.springframework.boot
            spring-boot-starter-logging
        
    

    7、使用:

    在接口上直接添加就可以

    @OperationLog(module = "添加商品模块", desc = "添加商品操作", operationType = OperationType.ADD)

    8、库里保存数据

     

  • 相关阅读:
    Electron安装问题
    【javaSE】初始类与对象
    基于Spring实现策略模式
    Visual Studio Code使用
    自己手写RISCV架构CPU-4其它指令
    spring-boot2.6.x兼容swagger2问题
    2739. 总行驶距离
    java毕业设计能源控制系统mybatis+源码+调试部署+系统+数据库+lw
    记录几道整型提升的题目
    入门力扣自学笔记190 C++ (题目编号:481)
  • 原文地址:https://blog.csdn.net/wufaqidong1/article/details/126466389