SpringBoot之路:自定义注解实现日志记录

只需在控制器方法上加上注解,就能保存日志

Maven依赖

需要引入SpringBoot的AOP依赖

1
<dependency>
2
    <groupId>org.springframework.boot</groupId>
3
    <artifactId>spring-boot-starter-aop</artifactId>
4
</dependency>

数据表

一张普通的日志表

1
CREATE TABLE `sys_operation_log` (
2
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '编号',
3
  `type` tinyint(1) NOT NULL COMMENT '操作类型(1:查询,2:插入,3:更新,4:删除)',
4
  `module` varchar(50) NOT NULL COMMENT '模块名称',
5
  `operation` varchar(50) NOT NULL COMMENT '操作描述',
6
  `successful` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否成功(0:否,1:是)',
7
  `remark` text COMMENT '备注',
8
  `create_time` datetime NOT NULL COMMENT '操作时间',
9
  `create_user` bigint(20) unsigned NOT NULL COMMENT '操作用户编号',
10
  PRIMARY KEY (`id`) USING BTREE
11
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COMMENT='系统操作日志表';

Service/Dao/Bean

使用MyBatisPlus快速创建CRUD,过于简单就不贴代码了

其中,LogTypeEnum这个枚举类后面为注解类使用而定义

1
@Getter
2
@AllArgsConstructor
3
public enum LogTypeEnum {
4
    
5
    /**
6
     * SELECT 查询
7
     */
8
    QUERY(1, "查询"),
9
    /**
10
     * INSERT 插入
11
     */
12
    SAVE(2, "新增"),
13
    /**
14
     * UPDATE 更新
15
     */
16
    UPDATE(3, "更新"),
17
    /**
18
     * UPDATE 逻辑删除
19
     */
20
    DELETE(4, "删除");
21
    
22
    /**
23
     * 字段值
24
     */
25
    private Integer value;
26
    /**
27
     * 字段名称
28
     */
29
    private String name;
30
}

注解类

首先需要定义一个@interface自定义注解类(字段根据实际使用环境来添加)

1
@Target(ElementType.METHOD)
2
@Retention(RetentionPolicy.RUNTIME)
3
public @interface OperationLog {
4
5
    LogTypeEnum type();
6
7
    String module() default "system";
8
9
    String operation();
10
11
}

切面

定义好注解类之后我们需要添加一个切面来实现注解

1
@Aspect
2
@Component
3
public class OperationLogAdvice {
4
    
5
    @Resource
6
    private SysOperationLogService sysOperationLogService;
7
    
8
    @Around(value = "@annotation(com.zjars.teamconfigure.common.annotation.OperationLog)")
9
    public Object saveLog(ProceedingJoinPoint joinPoint) throws Throwable {
10
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
11
        OperationLog operationLog = methodSignature.getMethod().getDeclaredAnnotation(OperationLog.class);
12
        
13
        String operation = operationLog.operation();
14
        String module = operationLog.module();
15
        LogTypeEnum type = operationLog.type();
16
        
17
        // 封装日志实体类
18
        SysOperationLog sysOperationLog = new SysOperationLog()
19
                .setOperation(operation)
20
                .setModule(module)
21
                .setType(type.getValue())
22
                .setCreateUser(1L)
23
                .setCreateTime(LocalDateTime.now());
24
        try {
25
            Object proceed = joinPoint.proceed();
26
            // 成功记录
27
            sysOperationLogService.save(sysOperationLog);
28
            return proceed;
29
        }catch (Exception e){
30
            sysOperationLog.setSuccessful(false).setRemark(e.getMessage());
31
            // 出错记录
32
            sysOperationLogService.save(sysOperationLog);
33
            throw e;
34
        }
35
    }
36
    
37
}

使用

到这一步就完成了注解类集成日志记录的操作了,接下来只需要在使用的控制器方法上加上@OperationLog就可以了

1
@OperationLog(type = LogTypeEnum.SAVE, operation = "新增XXX")
2
@PostMapping("/save")
3
public void save(XXX xxx) {
4
    //...
5
}
6
    
7
@OperationLog(type = LogTypeEnum.UPDATE, operation = "更新XXX")
8
@PostMapping("/update")
9
public void update(XXX xxx) {
10
    //...
11
}
12
    
13
@OperationLog(type = LogTypeEnum.DELETE, operation = "删除XXX")
14
@PostMapping("/delete")
15
public void delete(XXX xxx) {
16
    //...
17
}

调用接口后,会自动插入到日志表中

坚持原创技术分享,您的支持将鼓励我继续创作!