自定义注解+AOP处理操作日志,Springboot 拦截日志思路

操作日志的处理,用户在使用系统时会有各种操作行为,比如登录、查询信息、创建内容、变更密码、更改权限等等,归属到后端系统,其实就是请求接口后,做增删改查。为了回溯,操作日志不可避免,也就是要记录用户的这些操作行为。

常见做法是使用自定义注解, AOP 拦截,拿到访问 IP、业务名称、服务模块(时间是必须的)…

为了回顾一些概念,本篇博文,我来实现一个。

自定义注解

注解是一种能被编译器编译打包到 class 文件的元数据。我们常见的注解有两类:

由编译器识别使用的注解,这类很容易被忽略,因为是针对编译器,一般会自带生成,比如:override,这类注解不会打包到 class 文件。不信,我们去项目 target 目录下全局搜 override 试试,肯定搜不到。

第二类是项目代码运行时使用的注解,它们加载后一直存在 JVM 中,很多常见的注解,像 Spring 家族那些注解等等都是。这些注解本质还是手动使用 Java 代码实现功能,像之前我分享过的Spring笔记(03) SpringMVC底层实现模拟。这个过程就是自定义注解。

像现在,为了拦截接口,我们也要实现一个自定义注解,这里取名 BussinessLog

使用@interface定义注解,注解里可以配置参数,如果要配置参数,有几个“潜规则”要注意。

  • 有且必要配置一个 value 参数
  • 给参数设置默认值
  • 参数和普通类定义参数不一样,类似无参数方法

现在来看步骤:

第一步,使用@interface定义注解

public @interface BussinessLog {
    
}

第二步,添加参数,配置默认值

public @interface BussinessLog {
    //业务名称
    String value() default "";
    //服务模块
    ServiceEnum service() default ServiceEnum.LOGIN;
    //是否存入数据库
    boolean save() default true;
}

第三步,用元注解配置

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BussinessLog {
    //业务名称
    String value() default "";
    //服务模块
    ServiceEnum service() default ServiceEnum.LOGIN;
    //是否存入数据库
    boolean save() default true;
}

aop

AOP 不仅可以用来切(拦截)方法,也可以切注解,也就是说切入点可以是方法或注解,像这里就是注解。

我们需要编写一个切面类,切面类和普通类区别不大,一般切面类常带俩注解,@@Aspect@Component,如果有用到日志,可能还会有@Slf4j

@Slf4j
@Aspect
@Component
public class BussinessLogAspect {

    @Pointcut(value = "@annotation(com.***.BussinessLog)")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object writeLog(ProceedingJoinPoint point) throws Throwable {
        //先执行业务
        Object result = point.proceed();

        try {
        		//处理日志,打印或存入数据库
            handle(point);
        } catch (Exception e) {
            log.error("日志记录出错!", e);
        }
        return result;
    }

}

如上代码有两点要注意,切入点Pointcut填写BussinessLog注解的路径,其次先执行任务,也就是先进入 Controller,完成返回后再处理操作日志。一般要么打印输入到 log 文件,要么保存到数据库,分情况。

使用注解很简单,一般会放到 Controller层方法上。

怎么说呢?不管有用没,还是想加上这句
老郭种树原创,转载请加上自定义注解+AOP处理操作日志,Springboot 拦截日志思路
点赞

发表评论

邮箱地址不会被公开。 必填项已用*标注