当前位置:

首页 > 编程开发 > SpringBoot怎么利用AOP实现一个日志管理

SpringBoot怎么利用AOP实现一个日志管理

1.需求目前有这么个问题,有两个系统CSP和OMS,这俩系统共用的是同一套日志操作:Log;目前想区分下这俩系统的日志操作,那没办法了,只能重写一份Log的日志操作;你也可以参照若依框架的日志系统实现。2.新建一张日志表sys_oper_csp_log/*NavicatPremiumDataTransferSourceServer:jp-csc-adminSourceServerType:MySQLSourceServerVersion:50728SourceHost:rm-uf6miy84gu8u433

本文目录

    1. 需求

    目前有这么个问题,有两个系统CSP和OMS,这俩系统共用的是同一套日志操作:Log;目前想区分下这俩系统的日志操作,那没办法了,只能重写一份Log的日志操作;

    你也可以参照若依框架的日志系统实现。

    2. 新建一张日志表

    sys_oper_csp_log

    /*
     Navicat Premium Data Transfer
    
     Source Server         : jp-csc-admin
     Source Server Type    : MySQL
     Source Server Version : 50728
     Source Host           : rm-uf6miy84gu8u433x9.mysql.rds.aliyuncs.com:3306
     Source Schema         : jp_oms
    
     Target Server Type    : MySQL
     Target Server Version : 50728
     File Encoding         : 65001
    
     Date: 08/09/2022 09:21:45
    */
    
    SET NAMES utf8mb4;
    SET FOREIGN_KEY_CHECKS = 0;
    
    -- ----------------------------
    -- Table structure for sys_oper_csp_log
    -- ----------------------------
    DROP TABLE IF EXISTS `sys_oper_csp_log`;
    CREATE TABLE `sys_oper_csp_log`  (
      `oper_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '日志主键',
      `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '模块标题',
      `business_type` int(2) NULL DEFAULT 0 COMMENT '业务类型(0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据)',
      `method` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '方法名称',
      `request_method` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '请求方式',
      `operator_type` int(1) NULL DEFAULT 0 COMMENT '操作类别(0其它 1后台用户 2手机端用户)',
      `oper_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '操作人员',
      `dept_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '部门名称',
      `oper_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '请求URL',
      `oper_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '主机地址',
      `oper_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '操作地点',
      `oper_param` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '请求参数',
      `json_result` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '返回参数',
      `status` int(1) NULL DEFAULT 0 COMMENT '操作状态(0正常 1异常)',
      `error_msg` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '错误消息',
      `oper_time` datetime NULL DEFAULT NULL COMMENT '操作时间',
      PRIMARY KEY (`oper_id`) USING BTREE,
      INDEX `idx_time`(`oper_time`, `title`, `oper_name`) USING BTREE
    ) ENGINE = InnoD CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'CSP系统操作日志记录';

    3. 写相应的Controller层

    package com.juepeiscm.csp.controller.csplog;
    
    import com.juepeiscm.admin.api.domain.SysOperLog;
    import com.juepeiscm.common.core.controller.BaseController;
    import com.juepeiscm.common.core.domain.AjaxResult;
    import com.juepeiscm.common.core.page.TableDataInfo;
    import com.juepeiscm.common.enums.BusinessType;
    import com.juepeiscm.common.utils.poi.ExcelUtil;
    import com.juepeiscm.csp.annotation.CspLog;
    import com.juepeiscm.csp.domain.csplog.SysOperCspLog;
    import com.juepeiscm.csp.service.csplog.ISysOperCspLogService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.access.prepost.PreAuthorize;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.List;
    
    /**
     * 操作CSP系统日志
     * @Author: py.sun
     * @Date: 2022/9/7 14:51
     */
    @RestController
    @RequestMapping({"/csplog/opercsplog"})
    public class SysOperCsplogController extends BaseController {
        @Autowired
        private ISysOperCspLogService operCspLogService;
    
        public SysOperCsplogController() {
        }
    
        /**
         * 查询操作日志列表
         * @param sysOperCspLog
         * @return
         */
        @PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
        @GetMapping({"/list"})
        public TableDataInfo list(SysOperCspLog sysOperCspLog) {
            this.startPage();
            List list = this.operCspLogService.selectOperLogList(sysOperCspLog);
            return this.getDataTable(list);
        }
    
        /**
         * 查询系统模块的分类
         * @param
         * @return
         */
        @GetMapping({"/listTitle"})
        public TableDataInfo listTitle() {
            this.startPage();
            List list = this.operCspLogService.selectOperLogListTitle();
            return this.getDataTable(list);
        }
    
        @CspLog(
                title = "导出CSP系统日志",
                businessType = BusinessType.EXPORT
        )
        @PreAuthorize("@ss.hasPermi('monitor:operlog:export')")
        @GetMapping({"/export"})
        public AjaxResult export(SysOperCspLog operLog) {
            List list = this.operCspLogService.selectOperLogList(operLog);
            ExcelUtil util = new ExcelUtil(SysOperLog.class);
            return util.exportExcel(list, "操作CSP系统日志");
        }
    
        @CspLog(
                title = "操作CSP系统日志",
                businessType = BusinessType.DELETE
        )
        @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
        @DeleteMapping({"/{operIds}"})
        public AjaxResult remove(@PathVariable Long[] operIds) {
            return this.toAjax(this.operCspLogService.deleteOperLogByIds(operIds));
        }
    
        @CspLog(
                title = "清除CSP系统日志",
                businessType = BusinessType.CLEAN
        )
        @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
        @DeleteMapping({"/clean"})
        public AjaxResult clean() {
            this.operCspLogService.cleanOperLog();
            return AjaxResult.success();
        }
    
    
    }

    4.Service接口层

    package com.juepeiscm.csp.service.csplog;
    
    import com.juepeiscm.admin.api.domain.SysOperLog;
    import com.juepeiscm.csp.domain.csplog.SysOperCspLog;
    
    import java.util.List;
    
    /**
     * @Author: py.sun
     * @Date: 2022/9/7 15:02
     */
    public interface ISysOperCspLogService {
        void insertOperlog(SysOperCspLog var1);
    
        List selectOperLogList(SysOperCspLog var1);
    
        List selectOperLogListTitle();
    
        int deleteOperLogByIds(Long[] var1);
    
        SysOperLog selectOperLogById(Long var1);
    
        void cleanOperLog();
    }

    5.Service实现

    package com.juepeiscm.csp.service.impl.csplog;
    
    import com.juepeiscm.admin.api.domain.SysOperLog;
    import com.juepeiscm.common.core.domain.AjaxResult;
    import com.juepeiscm.common.core.domain.entity.SysDept;
    import com.juepeiscm.common.core.domain.entity.SysUser;
    import com.juepeiscm.common.core.domain.model.LoginUser;
    import com.juepeiscm.common.exception.CustomException;
    import com.juepeiscm.common.utils.SecurityUtils;
    import com.juepeiscm.common.utils.ServletUtils;
    import com.juepeiscm.common.utils.StringUtils;
    import com.juepeiscm.csp.domain.csplog.SysOperCspLog;
    import com.juepeiscm.csp.mapper.csplog.SysOperCspLogMapper;
    import com.juepeiscm.csp.service.csplog.ISysOperCspLogService;
    import com.juepeiscm.framework.web.service.TokenService;
    import com.juepeiscm.uam.service.ISysDeptService;
    import com.juepeiscm.uam.version.UamVersion;
    import org.apache.dubbo.config.annotation.Reference;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.util.List;
    
    /**
     * @Author: py.sun
     * @Date: 2022/9/7 15:03
     */
    @Service
    public class SysOperCspLogServiceImpl implements ISysOperCspLogService {
        @Autowired
        private SysOperCspLogMapper operLogMapper;
    
        @Autowired
        private TokenService tokenService;
    
        @Reference(version = UamVersion.idV)
        public ISysDeptService deptService;
    
        @Override
        public void insertOperlog(SysOperCspLog sysOperCspLog) {
            try {
                this.operLogMapper.insertOperlog(sysOperCspLog);
            } catch (Exception e) {
                e.printStackTrace();
                throw new CustomException("CSP系统日志插入失败,请联系管理员!!!");
            }
    
        }
    
        @Override
        public List selectOperLogList(SysOperCspLog sysOperCspLog) {
            return this.operLogMapper.selectOperLogList(sysOperCspLog);
        }
    
        @Override
        public List selectOperLogListTitle() {
            return this.operLogMapper.selectOperLogListTitle();
        }
    
        @Override
        public int deleteOperLogByIds(Long[] operIds) {
            return this.operLogMapper.deleteOperLogByIds(operIds);
        }
    
        @Override
        public SysOperLog selectOperLogById(Long operId) {
            return this.operLogMapper.selectOperLogById(operId);
        }
    
        @Override
        public void cleanOperLog() {
            this.operLogMapper.cleanOperLog();
        }
    }

    6.Mapper接口

    package com.juepeiscm.csp.mapper.csplog;
    
    import com.juepeiscm.admin.api.domain.SysOperLog;
    import com.juepeiscm.csp.domain.csplog.SysOperCspLog;
    
    import java.util.List;
    
    /**
     * @Author: py.sun
     * @Date: 2022/9/7 15:06
     */
    public interface SysOperCspLogMapper {
    
        void insertOperlog(SysOperCspLog var1);
    
        List selectOperLogList(SysOperCspLog sysOperCspLog);
    
        List selectOperLogListTitle();
    
        int deleteOperLogByIds(Long[] var1);
    
        SysOperLog selectOperLogById(Long var1);
    
        void cleanOperLog();
    }

    7.Mapper.xml(我用的是Mybatis)

    
    
    
    
        
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
        
    
        
            select oper_id, title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, oper_time
            from sys_oper_csp_log
        
    
        
            insert into sys_oper_csp_log(title, business_type, method, request_method, operator_type, oper_name, dept_name, oper_url, oper_ip, oper_location, oper_param, json_result, status, error_msg, oper_time)
            values (#{title}, #{businessType}, #{method}, #{requestMethod}, #{operatorType}, #{operName}, #{deptName}, #{operUrl}, #{operIp}, #{operLocation}, #{operParam}, #{jsonResult}, #{status}, #{errorMsg}, sysdate())
        
    
        
            
            
                
                    AND title like concat('%', #{title}, '%')
                
                
                    AND business_type = #{businessType}
                
                 0">
                    AND business_type in
                    
                        #{businessType}
                    
                
                
                    AND status = #{status}
                
                
                    AND oper_name like concat('%', #{operName}, '%')
                
                
                    and date_format(oper_time,'%y%m%d') >= date_format(#{params.beginTime},'%y%m%d')
                
                
                    and date_format(oper_time,'%y%m%d') <= date_format(#{params.endTime},'%y%m%d')
                
            
            order by oper_id desc
        
    
        
            delete from sys_oper_csp_log where oper_id in
            
                #{operId}
            
        
    
        
            
            where oper_id = #{operId}
        
    
        
            select distinct(title)  from sys_oper_csp_log
        
    
        
            truncate table sys_oper_csp_log
        
    
    

    8.CspLog

    定义一个日志管理的名称:CspLog

    package com.juepeiscm.csp.annotation;
    
    import com.juepeiscm.common.enums.BusinessType;
    import com.juepeiscm.common.enums.OperatorType;
    
    import java.lang.annotation.*;
    
    /**
     * CSP系统的日志管理
     * @Author: py.sun
     * @Date: 2022/9/7 14:42
     * @Target表示注解可以使用到哪些地方,可以是类,方法,或者是属性上,定义在ElementType枚举中:
     * @Retention作用是定义被它所注解的注解保留多久,一共有三种策略,定义在RetentionPolicy枚举中:
     *
     * 我们的@CspLog注解,可以作用在方法和参数上,将由编译器记录在类文件中,并在运行时由VM保留,因此可以反射性地读取。该注解是通过AOP进行解析的
     */
    @Target({ElementType.PARAMETER, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface CspLog {
        /**
         * 模块
         * @return
         */
        String title() default "";
    
        /**
         * 功能
         * @return
         */
        BusinessType businessType() default BusinessType.OTHER;
    
        /**
         * 操作人类别
         * @return
         */
        OperatorType operatorType() default OperatorType.MANAGE;
    
        /**
         * 是否保存请求的参数
         * @return
         */
        boolean isSaveRequestData() default true;
    }

    9.实体类SysOperCspLog

    package com.juepeiscm.csp.domain.csplog;
    
    import com.fasterxml.jackson.annotation.JsonFormat;
    import com.juepeiscm.common.annotation.Excel;
    import com.juepeiscm.common.core.domain.BaseEntity;
    
    import java.util.Date;
    
    /**
     * @Author: py.sun
     * @Date: 2022/9/7 15:04
     */
    public class SysOperCspLog extends BaseEntity {
        private static final long serialVersionUID = 1L;
        @Excel(
                name = "操作序号",
                cellType = Excel.ColumnType.NUMERIC
        )
        private Long operId;
        @Excel(
                name = "操作模块"
        )
        private String title;
        @Excel(
                name = "业务类型",
                readConverterExp = "0=其它,1=新增,2=修改,3=删除,4=授权,5=导出,6=导入,7=强退,8=生成代码,9=清空数据"
        )
        private Integer businessType;
        private Integer[] businessTypes;
        @Excel(
                name = "请求方法"
        )
        private String method;
        @Excel(
                name = "请求方式"
        )
        private String requestMethod;
        @Excel(
                name = "操作类别",
                readConverterExp = "0=其它,1=后台用户,2=手机端用户"
        )
        private Integer operatorType;
        @Excel(
                name = "操作人员"
        )
        private String operName;
        @Excel(
                name = "部门名称"
        )
        private String deptName;
        @Excel(
                name = "请求地址"
        )
        private String operUrl;
        @Excel(
                name = "操作地址"
        )
        private String operIp;
        @Excel(
                name = "操作地点"
        )
        private String operLocation;
        @Excel(
                name = "请求参数"
        )
        private String operParam;
        @Excel(
                name = "返回参数"
        )
        private String jsonResult;
        @Excel(
                name = "状态",
                readConverterExp = "0=正常,1=异常"
        )
        private Integer status;
        @Excel(
                name = "错误消息"
        )
        private String errorMsg;
        @JsonFormat(
                pattern = "yyyy-MM-dd HH:mm:ss"
        )
        @Excel(
                name = "操作时间",
                width = 30.0D,
                dateFormat = "yyyy-MM-dd HH:mm:ss"
        )
        private Date operTime;
    
        public SysOperCspLog() {
        }
    
        public Long getOperId() {
            return this.operId;
        }
    
        public void setOperId(Long operId) {
            this.operId = operId;
        }
    
        public String getTitle() {
            return this.title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public Integer getBusinessType() {
            return this.businessType;
        }
    
        public void setBusinessType(Integer businessType) {
            this.businessType = businessType;
        }
    
        public Integer[] getBusinessTypes() {
            return this.businessTypes;
        }
    
        public void setBusinessTypes(Integer[] businessTypes) {
            this.businessTypes = businessTypes;
        }
    
        public String getMethod() {
            return this.method;
        }
    
        public void setMethod(String method) {
            this.method = method;
        }
    
        public String getRequestMethod() {
            return this.requestMethod;
        }
    
        public void setRequestMethod(String requestMethod) {
            this.requestMethod = requestMethod;
        }
    
        public Integer getOperatorType() {
            return this.operatorType;
        }
    
        public void setOperatorType(Integer operatorType) {
            this.operatorType = operatorType;
        }
    
        public String getOperName() {
            return this.operName;
        }
    
        public void setOperName(String operName) {
            this.operName = operName;
        }
    
        public String getDeptName() {
            return this.deptName;
        }
    
        public void setDeptName(String deptName) {
            this.deptName = deptName;
        }
    
        public String getOperUrl() {
            return this.operUrl;
        }
    
        public void setOperUrl(String operUrl) {
            this.operUrl = operUrl;
        }
    
        public String getOperIp() {
            return this.operIp;
        }
    
        public void setOperIp(String operIp) {
            this.operIp = operIp;
        }
    
        public String getOperLocation() {
            return this.operLocation;
        }
    
        public void setOperLocation(String operLocation) {
            this.operLocation = operLocation;
        }
    
        public String getOperParam() {
            return this.operParam;
        }
    
        public void setOperParam(String operParam) {
            this.operParam = operParam;
        }
    
        public String getJsonResult() {
            return this.jsonResult;
        }
    
        public void setJsonResult(String jsonResult) {
            this.jsonResult = jsonResult;
        }
    
        public Integer getStatus() {
            return this.status;
        }
    
        public void setStatus(Integer status) {
            this.status = status;
        }
    
        public String getErrorMsg() {
            return this.errorMsg;
        }
    
        public void setErrorMsg(String errorMsg) {
            this.errorMsg = errorMsg;
        }
    
        public Date getOperTime() {
            return this.operTime;
        }
    
        public void setOperTime(Date operTime) {
            this.operTime = operTime;
        }
    }

    10. 定义日志管理的切面

    大家一定要记住哈,所有针对实体的SysOperCspLog赋值操作必须在这里main执行。

    package com.juepeiscm.csp.controller.utils;
    
    import com.alibaba.fastjson.JSON;
    import com.juepeiscm.common.core.domain.entity.SysDept;
    import com.juepeiscm.common.core.domain.model.LoginUser;
    import com.juepeiscm.common.enums.BusinessStatus;
    import com.juepeiscm.common.enums.HttpMethod;
    import com.juepeiscm.common.utils.ServletUtils;
    import com.juepeiscm.common.utils.StringUtils;
    import com.juepeiscm.common.utils.ip.IpUtils;
    import com.juepeiscm.common.utils.spring.SpringUtils;
    import com.juepeiscm.csp.annotation.CspLog;
    import com.juepeiscm.csp.domain.csplog.SysOperCspLog;
    import com.juepeiscm.framework.aspectj.LogAspect;
    import com.juepeiscm.framework.manager.AsyncManager;
    import com.juepeiscm.framework.web.service.TokenService;
    import com.juepeiscm.uam.service.ISysDeptService;
    import com.juepeiscm.uam.version.UamVersion;
    import org.apache.dubbo.config.annotation.Reference;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.Signature;
    import org.aspectj.lang.annotation.AfterReturning;
    import org.aspectj.lang.annotation.AfterThrowing;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    import org.springframework.validation.BindingResult;
    import org.springframework.web.multipart.MultipartFile;
    import org.springframework.web.servlet.HandlerMapping;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.lang.reflect.Method;
    import java.util.Collection;
    import java.util.Iterator;
    import java.util.Map;
    
    /**
     * @Author: py.sun
     * @Date: 2022/9/7 16:31
     * 操作日志记录处理
     */
    @Aspect
    @Component
    public class CspLogAspect {
        private static final Logger log = LoggerFactory.getLogger(CspLog.class);
    
        @Reference(version = UamVersion.idV)
        public ISysDeptService deptService;
    
        public CspLogAspect() {
        }
    
        //把@CspLog配置为切入点。   配置织入点
        @Pointcut("@annotation(com.juepeiscm.csp.annotation.CspLog)")
        public void logPointCut() {
        }
    
        //拦截异常操作
        // 处理完请求后执行该方法。也就是用@CspLog注解的方法,执行完后,调用handleLog方法,处理返回结果。
        @AfterReturning(
                pointcut = "logPointCut()",
                returning = "jsonResult"
        )
        public void doAfterReturning(JoinPoint joinPoint, Object jsonResult) {
            this.handleLog(joinPoint, (Exception)null, jsonResult);
        }
    
        @AfterThrowing(
                value = "logPointCut()",
                throwing = "e"
        )
        public void doAfterThrowing(JoinPoint joinPoint, Exception e) {
            this.handleLog(joinPoint, e, (Object)null);
        }
    
        // 如果函数抛出了异常,也是执行handleLog方法,不过和正常返回的参数不一样,此处是为了处理异常。
        protected void handleLog(JoinPoint joinPoint, Exception e, Object jsonResult) {
            try {
                // 获得注解
                CspLog controllerLog = this.getAnnotationLog(joinPoint);
                if (controllerLog == null) {
                    return;
                }
    
                // 获取当前的用户
                LoginUser loginUser = ((TokenService) SpringUtils.getBean(TokenService.class)).getLoginUser(ServletUtils.getRequest());
                // *========数据库日志=========*//
                SysOperCspLog operLog = new SysOperCspLog();
                operLog.setStatus(BusinessStatus.SUCCESS.ordinal());
                // 请求的地址
                String ip = IpUtils.getIpAddr(ServletUtils.getRequest());
                operLog.setOperIp(ip);
                // 返回参数
                operLog.setJsonResult(JSON.toJSONString(jsonResult));
                operLog.setOperUrl(ServletUtils.getRequest().getRequestURI());
                if (loginUser != null) {
                    operLog.setOperName(loginUser.getUsername());
                }
    
                // 获取当前登录用户的部门名称
                SysDept sysDept = deptService.selectDeptIdByUserIdAndAppId(loginUser.getUser().getUserId(), "oms");
                if(sysDept != null && StringUtils.isNotEmpty(sysDept.getDeptName())){
                        operLog.setDeptName(sysDept.getDeptName());
                }
    
                if (e != null) {
                    operLog.setStatus(BusinessStatus.FAIL.ordinal());
                    operLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
                }
    
                // 设置方法名称
                String className = joinPoint.getTarget().getClass().getName();
                String methodName = joinPoint.getSignature().getName();
                operLog.setMethod(className + "." + methodName + "()");
                // 设置请求方式
                operLog.setRequestMethod(ServletUtils.getRequest().getMethod());
                // 处理设置注解上的参数
                this.getControllerMethodDescription(joinPoint, controllerLog, operLog);
                // 保存数据库
                AsyncManager.me().execute(AsyncFactoryCsp.recordOper(operLog));
            } catch (Exception var10) {
                // 记录本地异常日志
                log.error("==前置通知异常==");
                log.error("异常信息:{}", var10.getMessage());
                var10.printStackTrace();
            }
    
        }
    
        public void getControllerMethodDescription(JoinPoint joinPoint, CspLog log, SysOperCspLog operLog) throws Exception {
            operLog.setBusinessType(log.businessType().ordinal());
            operLog.setTitle(log.title());
            operLog.setOperatorType(log.operatorType().ordinal());
            if (log.isSaveRequestData()) {
                this.setRequestValue(joinPoint, operLog);
            }
    
        }
    
        private void setRequestValue(JoinPoint joinPoint, SysOperCspLog operLog) throws Exception {
            String requestMethod = operLog.getRequestMethod();
            if (!HttpMethod.PUT.name().equals(requestMethod) && !HttpMethod.POST.name().equals(requestMethod)) {
                Map paramsMap = (Map)ServletUtils.getRequest().getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
                operLog.setOperParam(StringUtils.substring(paramsMap.toString(), 0, 2000));
            } else {
                String params = this.argsArrayToString(joinPoint.getArgs());
                operLog.setOperParam(StringUtils.substring(params, 0, 2000));
            }
    
        }
    
        private CspLog getAnnotationLog(JoinPoint joinPoint) throws Exception {
            Signature signature = joinPoint.getSignature();
            MethodSignature methodSignature = (MethodSignature)signature;
            Method method = methodSignature.getMethod();
            return method != null ? (CspLog)method.getAnnotation(CspLog.class) : null;
        }
    
        private String argsArrayToString(Object[] paramsArray) {
            String params = "";
            if (paramsArray != null && paramsArray.length > 0) {
                for(int i = 0; i < paramsArray.length; ++i) {
                    if (StringUtils.isNotNull(paramsArray[i]) && !this.isFilterObject(paramsArray[i])) {
                        Object jsonObj = JSON.toJSON(paramsArray[i]);
                        params = params + jsonObj.toString() + " ";
                    }
                }
            }
    
            return params.trim();
        }
    
        public boolean isFilterObject(Object o) {
            Class clazz = o.getClass();
            if (clazz.isArray()) {
                return clazz.getComponentType().isAssignableFrom(MultipartFile.class);
            } else {
                Iterator iter;
                if (Collection.class.isAssignableFrom(clazz)) {
                    Collection collection = (Collection)o;
                    iter = collection.iterator();
                    if (iter.hasNext()) {
                        return iter.next() instanceof MultipartFile;
                    }
                } else if (Map.class.isAssignableFrom(clazz)) {
                    Map map = (Map)o;
                    iter = map.entrySet().iterator();
                    if (iter.hasNext()) {
                        Map.Entry entry = (Map.Entry)iter.next();
                        return entry.getValue() instanceof MultipartFile;
                    }
                }
    
                return o instanceof MultipartFile || o instanceof HttpServletRequest || o instanceof HttpServletResponse || o instanceof BindingResult;
            }
        }
    }

    11.AsyncFactoryCsp

    package com.juepeiscm.csp.controller.utils;
    import com.juepeiscm.common.utils.ip.AddressUtils;
    import com.juepeiscm.common.utils.spring.SpringUtils;
    import com.juepeiscm.csp.domain.csplog.SysOperCspLog;
    import com.juepeiscm.csp.service.csplog.ISysOperCspLogService;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.util.TimerTask;
    
    /**
     * @Author: py.sun
     * @Date: 2022/9/7 16:47
     */
    public class AsyncFactoryCsp {
        private static final Logger sys_user_logger = LoggerFactory.getLogger("sys-user");
    
        public AsyncFactoryCsp() {
        }
    
        public static TimerTask recordOper(final SysOperCspLog operLog) {
            return new TimerTask() {
                public void run() {
                    operLog.setOperLocation(AddressUtils.getRealAddressByIP(operLog.getOperIp()));
                    ((ISysOperCspLogService) SpringUtils.getBean(ISysOperCspLogService.class)).insertOperlog(operLog);
                }
            };
        }
    }

    12. 写一个Controller的Demo来执行一条日志试试

    在这里插入代码片package com.juepeiscm.csp.controller.order;

    在这里插入代码片package com.juepeiscm.csp.controller.order;
    
    import com.alibaba.fastjson.JSON;
    import com.juepeiscm.admin.api.service.ISysDictDataService;
    import com.juepeiscm.common.annotation.RepeatSubmit;
    import com.juepeiscm.common.core.controller.BaseController;
    import com.juepeiscm.common.core.domain.AjaxResult;
    import com.juepeiscm.common.core.domain.entity.SysDictData;
    import com.juepeiscm.common.core.page.TableDataInfo;
    import com.juepeiscm.common.enums.BusinessType;
    import com.juepeiscm.common.exception.BaseException;
    import com.juepeiscm.common.utils.StringUtils;
    import com.juepeiscm.common.utils.poi.ExcelUtil;
    import com.juepeiscm.csp.annotation.CspLog;
    import com.juepeiscm.csp.domain.order.CspGodownEntry;
    import com.juepeiscm.csp.domain.order.CspGodownEntryDetails;
    import com.juepeiscm.csp.service.common.MenuLogService;
    import com.juepeiscm.csp.service.data.ICspGoodsdataService;
    import com.juepeiscm.csp.service.order.ICspGodownEntryService;
    import com.juepeiscm.csp.vo.GodownEntryExcel;
    import com.juepeiscm.csp.vo.GoodsDataForGodownEntryDetails;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.access.prepost.PreAuthorize;
    import org.springframework.util.CollectionUtils;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.multipart.MultipartFile;
    
    import javax.validation.Valid;
    import java.math.BigDecimal;
    import java.math.RoundingMode;
    import java.util.*;
    import java.util.stream.Collectors;
    
    /**
     * 入库订单Controller
     *
     * @author juepeiscm
     * @date 2021-07-23
     */
    @Api(tags = "入库订单接口")
    @RestController
    @RequestMapping("/order/godownEntry")
    public class CspGodownEntryController extends BaseController {
    
        private static final Logger logger = LoggerFactory.getLogger(CspGodownEntryController.class);
    
        @Autowired
        private ICspGodownEntryService cspGodownEntryService;
        @Autowired
        private ICspGoodsdataService goodsDataService;
        @Autowired
        private MenuLogService menuLogService;
        @Autowired
        private ISysDictDataService sysDictDataService;
    
        /**
         * 新增入库订单Demo
         */
        @PreAuthorize("@ss.hasPermi('order:godownEntry:add')")
        @ApiOperation(value = "新增入库订单")
        @CspLog(title = "入库订单demo4", businessType = BusinessType.INSERT)
        @PostMapping("/addOrder")
        @RepeatSubmit
        public AjaxResult addDemo(@RequestBody @Valid CspGodownEntry godownEntry) {
            try {
                return toAjax(cspGodownEntryService.insertOmsGodownEntry(godownEntry));
            } catch (Exception e) {
                e.printStackTrace();
                return AjaxResult.error("新增失败,请联系管理员");
            }
        }
    }

    测试下,看看数据库内容

    SpringBoot怎么利用AOP实现一个日志管理

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    Java实现AOP日志记录配置与代码详解
    Java实现AOP日志记录配置与代码详解

    AOP日志记录通过将日志功能与业务逻辑解耦,使代码更清晰、维护更便捷。1.首先需引入SpringAOP和AspectJ依赖;2.定义切点(Pointcut)指定拦截方法;3.编写通知(Advice)处理日志逻辑,如@Before、@AfterReturning等;4.创建切面(Aspect)整合切点与通知,并标注@Aspect和@Component;5.启用AOP自动代理。敏感数据可通过脱敏、限制记录字段或调整日志级别来避免泄露。性能影响取决于日志复杂度,建议异步记录和优化操作。选择切点表达式时应结合方法

    Spring框架中 AOP(面向方面编程)是如何实现的?
    Spring框架中 AOP(面向方面编程)是如何实现的?

    SpringAOP基于Java动态代理来实现面向方面编程,允许在不修改原始代码情况下,在方法执行前后插入附加逻辑。具体步骤如下:创建代理对象,使用Proxy.newProxyInstance()方法,提供类加载器、接口和调用处理器。调用处理器的invoke()方法,获取目标对象、拦截器链,并依次调用拦截器invoke()。最后,如果没有异常,调用目标对象的方法。

    PHP中的面向切面编程(AOP)初探
    PHP中的面向切面编程(AOP)初探

    随着软件开发的不断发展,越来越多的编程语言和技术层出不穷。其中,PHP作为一门广泛应用于Web开发的脚本语言,在不断发展和革新的过程中,也涌现出了许多重要的概念和技术,如面向对象编程(OOP)、设计模式等,而今天我们要探讨的是PHP中的另一种编程方式——面向切面编程(AOP)。什么是AOP?AOP,全称是Aspect-OrientedProgramming

    springBoot项目常用目录有哪些
    springBoot项目常用目录有哪些

    springBoot项目常用目录springBoot项目的目录结构及名规范介绍基于SpringBoot开发时的目录结构及命名规范,通过介绍能够为你解决,在实际项目中如何规划目录结构?如何命名目录更规范?各个目录分别代表什么含义?等三个问题。目录说明servicex//项目名|-admin-ui//管理服务前端代码(一般将UI和SERVICE放到一个工程中,便于管理)|-servicex-auth//模块1|-servicex-common//模块2|-servicex-gateway//模块3|-serv

    探索Spring Boot架构:深入解析框架内部机制
    探索Spring Boot架构:深入解析框架内部机制

    SpringBoot的架构可以分为以下几个主要组件:Spring核心模块:springBoot的核心模块提供了Spring框架的基本功能,包括依赖注入、aop、事务管理等。这些模块是Spring应用程序的基础,为SpringBoot的开发提供了坚实的基础。SpringBootStarter:SpringBootStarter是一个预先配置好的依赖项集合,它可以帮助开发者快速构建Spring应用程序。SpringBootStarter提供了各种各样的依赖项,涵盖了各种常用的功能,如web开发、数据访问、安全

    解析SpringBoot和SpringMVC之间的异同
    解析SpringBoot和SpringMVC之间的异同

    解析SpringBoot和SpringMVC之间的异同SpringBoot和SpringMVC是Java领域中非常重要的开发框架。虽然它们都属于Spring框架的一部分,但是在使用和功能上有一些明显的区别。本文将对SpringBoot和SpringMVC进行比较,解析它们之间的异同。首先,让我们来了解一下SpringBoot。SpringBo

    深入了解Spring中AOP的典型应用方式
    深入了解Spring中AOP的典型应用方式

    探索Spring中AOP的常见应用方式概述:随着软件开发的不断发展,业务逻辑的复杂性也日益增加。为了提高代码的可维护性和重用性,以及实现切面关注点的分离,面向切面编程(AOP)的概念被引入到软件开发中。Spring框架是Java开发中广泛应用的框架之一,也提供了强大的AOP支持。本文将探索Spring中AOP的常见应用方式,并提供具体的代码示例。一、前置通知

    解析Spring AOP的常见应用场景
    解析Spring AOP的常见应用场景

    Spring中AOP的常见应用方式解析引言:在软件开发过程中,面向切面编程(AOP)是一种很重要的技术,它能够通过在程序运行期间动态地将特定的代码片段织入到目标方法中,提供额外的功能和扩展。而Spring作为一个强大的开发框架,提供了丰富的AOP支持,本文将详细介绍Spring中AOP的常见应用方式,包括声明式和编程式两种方式,并提供具体的代码示例。一、声明

    探索SpringCloud和SpringBoot在微服务领域的不同应用方式
    探索SpringCloud和SpringBoot在微服务领域的不同应用方式

    近年来,随着云计算和分布式架构的兴起,微服务架构的应用越来越广泛。而SpringCloud和SpringBoot作为Java开发中的两个重要框架,对于微服务的实现起到了重要的作用。然而,很多人对于它们在微服务领域的不同应用方式还存在一定的疑惑。本文将从不同的角度探索SpringCloud和SpringBoot在微服务中的应用方式。首先,我们来了解一下Spri

    SpringBoot和SpringMVC有何区别?
    SpringBoot和SpringMVC有何区别?

    SpringBoot与SpringMVC的不同之处在哪里?SpringBoot和SpringMVC是两个非常流行的Java开发框架,用于构建Web应用程序。尽管它们经常分别被使用,但它们之间的不同之处也是很明显的。首先,SpringBoot可以被看作是一个Spring框架的扩展或者增强版。它旨在简化Spring应用程序的初始化和配置过程,以帮助开发人

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。