前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Boot学习 - Spring Boot AOP记录用户操作日志

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

作者头像
Li_XiaoJin
发布2022-06-10 20:36:21
5320
发布2022-06-10 20:36:21
举报
文章被收录于专栏:Lixj's BlogLixj's Blog

在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记录用户操作日志

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-10-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 自定义注解
  • 创建数据库表和实体
  • 保存日志的方法
  • 切面和切点
  • 测试
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档