Spring Boot学习 - Spring Boot AOP记录用户操作日志

2022-06-10 20:36:21 浏览数 (1)

在Spring框架中,使用AOP配合自定义注解可以方便的实现用户操作的监控。

先引入依赖

代码语言:javascript复制
<!-- aop依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
自定义注解
代码语言:javascript复制
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
    String value() default "";
}
创建数据库表和实体

数据库表:

代码语言:javascript复制
DROP TABLE IF EXISTS `sys_log`;
CREATE TABLE `sys_log`  (
  `ID` int(11) NULL DEFAULT NULL,
  `USERNAME` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `OPERATION` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `TIME` int(11) NULL DEFAULT NULL,
  `METHOD` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `PARAMS` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `IP` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `CREATE_TIME` datetime(0) NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

对应实体:

代码语言:javascript复制
@Data
public class SysLog {
    private Integer ID;

    private String USERNAME;

    private String OPERATION;

    private Integer TIME;

    private String METHOD;

    private String PARAMS;

    private String IP;

    private Date CREATE_TIME;
}
保存日志的方法
代码语言:javascript复制
@Component
@Mapper
public interface SysLogMapper {

    @Insert("INSERT INTO `sys_log`(`ID`, `USERNAME`, `OPERATION`, `TIME`, `METHOD`, `PARAMS`, `IP`, `CREATE_TIME`) VALUES (#{ID}, #{USERNAME}, #{OPERATION}, #{TIME}, #{METHOD}, #{PARAMS}, #{IP}, #{CREATE_TIME})")
    void saveSysLog(SysLog syslog);
}
切面和切点
代码语言:javascript复制
@Aspect
@Component
public class LogAspect {

    @Autowired
    private SysLogMapper sysLogMapper;

    @Pointcut("@annotation(com.example.lixj.annotation.Log)")
    public void pointcut() { }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point) {
        Object result = null;
        long beginTime = System.currentTimeMillis();
        try {
            // 执行方法
            result = point.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        // 执行时长(毫秒)
        long time = System.currentTimeMillis() - beginTime;
        // 保存日志
        saveLog(point, time);
        return result;
    }

    private void saveLog(ProceedingJoinPoint joinPoint, long time) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        SysLog sysLog = new SysLog();
        Log logAnnotation = method.getAnnotation(Log.class);
        if (logAnnotation != null) {
            // 注解上的描述
            sysLog.setOPERATION(logAnnotation.value());
        }
        // 请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLog.setMETHOD(className   "."   methodName   "()");
        // 请求的方法参数值
        Object[] args = joinPoint.getArgs();
        // 请求的方法参数名称
        LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
        String[] paramNames = u.getParameterNames(method);
        if (args != null && paramNames != null) {
            String params = "";
            for (int i = 0; i < args.length; i  ) {
                params  = "  "   paramNames[i]   ": "   args[i];
            }
            sysLog.setPARAMS(params);
        }
        // 获取request
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        // 设置IP地址
        sysLog.setIP(request.getHeader("x-forwarded-for") == null ? request.getRemoteAddr() : request.getHeader("x-forwarded-for"));
        // 模拟一个用户名
        sysLog.setUSERNAME("lixj");
        sysLog.setTIME((int) time);
        sysLog.setID(new Random().nextInt());
        //取当前时间
        Date nowdate=new Date();
        //转换时间格式
        SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sysLog.setCREATE_TIME(Timestamp.valueOf(simpleDate.format(nowdate)));
        // 保存系统日志
        sysLogMapper.saveSysLog(sysLog);
        System.out.println(true);
    }

}
测试
代码语言:javascript复制
@RestController
public class TestLogController {
    @Log("执行方法一")
    @GetMapping(value = "/one")
    public void method1(String name) {
    }

    @Log("执行方法二")
    @GetMapping(value = "two")
    public void method2() throws InterruptedException {
        Thread.sleep(2000);
    }

    @Log("执行方法三")
    @GetMapping(value = "three")
    public void method3(String name, String age) {
    }
}

启动项目,访问相关链接

查看数据库入表情况

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可 Links: https://lixj.fun/archives/springboot学习-springbootaop记录用户操作日志

0 人点赞