部门管理系统Spring AOP实现日志记录接口案例开发

需求分析

在开发过程中,为了记录系统操作行为,我们通常需要实现操作日志功能。本案例要求对系统中增、删、改等接口的操作日志记录到数据库表中,具体需求包括:

  1. 日志内容

    • 操作人(从请求头中的 Token 中解析获取当前登录用户的 ID)。

    • 操作时间。

    • 执行方法的全类名、方法名。

    • 方法运行时参数、返回值、执行耗时。

  2. 日志存储:日志信息需要保存到数据库表 operate_log 中。

  3. AOP 设计

    • 采用 @Around 环绕通知实现。

    • 切入点表达式基于自定义注解 @Log,方便灵活标注需要记录日志的方法。

代码解读

日志实体类:OperateLog 

@Data
@NoArgsConstructor
@AllArgsConstructor
public class OperateLog {private Integer id; //IDprivate Integer operateEmpId; //操作人IDprivate LocalDateTime operateTime; //操作时间private String className; //操作类名private String methodName; //操作方法名private String methodParams; //操作方法参数private String returnValue; //操作方法返回值private Long costTime; //操作耗时//页面展示字段private String operateEmpName; //操作人姓名
}
  1. 注解 @Data

    • 自动生成 Getter、Setter 等常用方法。

  2. 字段定义

    • 包含日志记录的所有字段,例如操作人、操作时间、方法名、返回值等。

  3. 页面展示字段

    • 添加 operateEmpName 字段,方便在日志展示页面中显示操作人姓名。

  4. 构造方法

    • 使用 @AllArgsConstructor@NoArgsConstructor 提供全参和无参构造器。

AOP 切面类:OperateLogAspect 

@Slf4j
@Aspect
@Component
public class OperateLogAspect {@Autowiredprivate OperateLogMapper operateLogMapper;@Autowiredprivate HttpServletRequest request;@Around("@annotation(com.zhang.anno.Log)")public Object record(ProceedingJoinPoint pjp) throws Throwable {// 获取操作人的 IDString jwt = request.getHeader("token");Claims claims = JwtUtils.parseJWT(jwt);Integer empId = Integer.parseInt(claims.get("id").toString());// 记录操作时间LocalDateTime operateTime = LocalDateTime.now();// 获取类名和方法名String className = pjp.getTarget().getClass().getName();String methodName = pjp.getSignature().getName();// 获取方法参数String methodParams = Arrays.toString(pjp.getArgs());// 记录方法执行时间long begin = System.currentTimeMillis();Object result = pjp.proceed(); // 调用原始方法long end = System.currentTimeMillis();// 构建操作日志对象OperateLog operateLog = new OperateLog(null, empId, operateTime, className,                             methodName, methodParams, result.toString(), end - begin, null);// 保存日志到数据库operateLogMapper.insert(operateLog);return result;}
}
  1. 注解 @Aspect@Component

    • @Aspect 表示这是一个切面类。

    • @Component 将切面类注册为 Spring 的 Bean。@Aspect 本身只标识一个类为切面,并不意味着该类会自动生效。配合 @Component 配置注册为 Bean 后,Spring AOP 框架才能找到并应用这个切面逻辑。

  2. 切入点表达式@Around("@annotation(com.zhang.anno.Log)")

    • 只对标注了 @Log 注解的方法生效。

  3. ProceedingJoinPoint

    • 用于获取切点方法的详细信息,例如类名、方法名、参数等。

    • 使用 proceed() 方法调用原始业务逻辑。

  4. 日志数据的采集

    • 操作人通过解析 Token 获取。

    • 操作时间、方法参数、返回值、执行耗时均在切面逻辑中记录。

  5. 日志的存储

    • 通过调用 OperateLogMapperinsert 方法将日志保存到数据库中。

数据库访问层:OperateLogMapper

@Mapper
public interface OperateLogMapper {@Insert("insert into operate_log (operate_emp_id, operate_time, class_name, method_name, method_params, return_value, cost_time) " +"values (#{operateEmpId}, #{operateTime}, #{className}, #{methodName}, #{methodParams}, #{returnValue}, #{costTime});")public void insert(OperateLog log);
}
代码说明
  1. 注解 @Mapper

    • 标记为 MyBatis 的 Mapper 接口。

  2. SQL 语句

    • INSERT 语句将日志各字段存储到 operate_log 表。

  3. 参数绑定

    • 使用 #{} 语法绑定 OperateLog 对象中的字段。

总结

通过使用 Spring AOP ,本案例实现了增、删、改接口操作日志的记录功能,主要包含以下亮点:

  1. 高内聚低耦合:通过 AOP 实现日志功能,与业务代码解耦,提高代码复用性和可维护性。

  2. 灵活扩展:使用自定义注解 @Log 标注需要记录日志的方法,方便灵活扩展。

  3. 操作全面:日志记录内容详尽,包括操作人、操作时间、类名、方法名、参数、返回值及耗时。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/888476.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenVas安装步骤及报错问题

安装步骤 1、更新系统 apt update && apt upgrade && apt dist-upgrade 2、安装openvas apt-get install openvas 3、初始化 gvm-setup 时间要很久 4、检查安装结果 gvm-check-setup 安装成功 5、设置用户名和密码,都为admin sudo runuse…

深度学习之pth转换为onnx时修改模型定义‌

文章目录 概述实现步骤python代码 概述 在将PyTorch模型(.pth文件)转换为ONNX格式时,通常的转换过程是通过torch.onnx.export函数来实现的。这个过程主要是将PyTorch模型的计算图导出为ONNX格式,以便在其他框架或环境中使用。 在…

STL算法之sort

STL所提供的各式各样算法中&#xff0c;sort()是最复杂最庞大的一个。这个算法接受两个RandomAccessIterators(随机存取迭代器)&#xff0c;然后将区间内的所有元素以渐增方式由小到大重新排列。还有一个版本则是允许用户指定一个仿函数代替operator<作为排序标准。STL的所有…

解决Tomcat运行时错误:“Address localhost:1099 is already in use”

目录 背景: 过程&#xff1a; 报错的原因&#xff1a; 解决的方法&#xff1a; 总结&#xff1a; 直接结束Java.exe进程&#xff1a; 使用neststat -aon | findstr 1099 命令&#xff1a; 选择建议&#xff1a; 背景: 准备运行Tomcat服务器调试项目时&#xff0c;程序下…

AJAX三、XHR,基本使用,查询参数,数据提交,promise的三种状态,封装-简易axios-获取省份列表 / 获取地区列表 / 注册用户,天气预报

一、XMLHttpRequest基本使用 XMLHttpRequest&#xff08;XHR&#xff09;对象用于与服务器交互。 二、XMLHttpRequest-查询参数 语法: 用 & 符号分隔的键/值对列表 三、XMLHttpRequest-数据提交 核心步骤 : 1. 请求头 设置 Content-Type 2. 请求体 携带 符合要求 的数…

矩阵加法        ‌‍‎‏

矩阵加法 C语言代码C 语言代码Java语言代码Python语言代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 输入两个n行m列的矩阵A和B&#xff0c;输出它们的和AB。 输入 第一行包含两个整数n和m&#xff0c;表示矩阵的行数和列数。1 <…

flink-connector-mysql-cdc:01 mysql-cdc础配置代码演示

flink-connector-mysql-cdc&#xff1a; 01 mysql-cdc基础配置代码演示02 mysql-cdc高级扩展03 mysql-cdc常见问题汇总04 mysql-cdc-kafka生产级代码分享05 flink-kafka-doris生产级代码分享06 flink-kafka-hudi生产级代码分享 flink-cdc版本&#xff1a;3.2.0 flink版本&…

ELK的Filebeat

目录 传送门前言一、概念1. 主要功能2. 架构3. 使用场景4. 模块5. 监控与管理 二、下载地址三、Linux下7.6.2版本安装filebeat.yml配置文件参考&#xff08;不要直接拷贝用&#xff09;多行匹配配置过滤配置最终配置&#xff08;一、多行匹配、直接读取日志文件、EFK方案&#…

HTML 添加 文本水印

body,html {margin: 0;height: 100vh;width: 100vw;} // 自定义文案const setting {text: "水印文案", // 水印内容innerDate: true, // 在水印下方增加日期width: 110, // 水印宽度};// 自定义文字水印const watermark (function () {return {build: function (a…

Android平台GB28181设备接入模块如何支持GB28181云端录像补录

技术背景 GB28181 的补录功能是一种用于弥补视频数据缺失的重要机制。在实际的视频监控场景中&#xff0c;由于网络不稳定、设备故障等多种因素&#xff0c;可能会导致视频数据在上云或存储过程中出现缺失&#xff0c;无法保证数据的完整性。GB28181 的补录功能就是为了解决这…

高级java每日一道面试题-2024年12月04日-JVM篇-什么是指针碰撞?

如果有遗漏,评论区告诉我进行补充 面试官: 什么是指针碰撞? 我回答: 在Java高级面试中&#xff0c;指针碰撞是一个重要而基础的概念&#xff0c;它涉及到JVM在堆内存中分配对象时的内存管理机制。以下是对指针碰撞的详细解释&#xff1a; 一、定义 指针碰撞&#xff08;B…

SpringBoot如何使用EasyExcel实现表格导出(简洁快速入门版本)

前言 前面给大家介绍了动态表头的导入&#xff0c;这篇文章给大家介绍如何实现导出 前面给大家介绍了动态表头的导入&#xff0c;我们了解了如何通过EasyExcel灵活地读取结构不固定的Excel文件。这次&#xff0c;我们将目光转向数据导出——即如何将数据以Excel文件的形式输出…

Web 毕设篇-适合小白、初级入门练手的 Spring Boot Web 毕业设计项目:智行无忧停车场管理系统(前后端源码 + 数据库 sql 脚本)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 项目介绍 1.1 项目功能 2.0 用户登录功能 3.0 首页界面 4.0 车辆信息管理功能 5.0 停车位管理功能 6.0 入场登记管理功能 7.0 预约管理功能 8.0 收费规则功能 9.0…

365天深度学习训练营-第P7周:马铃薯病害识别(VGG-16复现)

文为「365天深度学习训练营」内部文章 参考本文所写记录性文章&#xff0c;请在文章开头带上「&#x1f449;声明」 &#x1f37a; 要求&#xff1a; 自己搭建VGG-16网络框架【达成√】调用官方的VGG-16网络框架【达成√】如何查看模型的参数量以及相关指标【达成√】 &#…

前端如何实现Pinia 持久化插件 Persist步骤详解

在 Vue 3 项目中&#xff0c;Pinia 是官方推荐的状态管理库&#xff0c;而 Pinia Persisted State 插件可以帮助我们将 Pinia 的状态持久化到浏览器的存储中&#xff08;例如 localStorage 或 sessionStorage&#xff09;&#xff0c;这样即使页面刷新后&#xff0c;状态仍然能…

芯食代冻干科技研究院:创新与品质并重,推动家用冻干机高质量发展

11月25日,芯食代首届食品冻干前沿与智能化升级创新大会在江苏常州成功举办。本次大会由芯食代冻干科技研究院(江苏)有限公司与芯食代(上海)科技发展有限公司联合主办,云集学界专家教授、商界企业精英,共议家用冻干机的未来创新发展。作为创新大会,芯食代冻干科技研究院也在本次…

项目基于oshi库快速搭建一个cpu监控面板

后端&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.github.oshi</groupId><artifactId>oshi-…

什么是上下文管理器?如何使用 with 语句?

上下文管理器&#xff08;Context Manager&#xff09;是Python中的一种协议&#xff0c;它允许你在特定的语境下分配和释放资源。 通常来说&#xff0c;当你需要确保某些操作在使用资源之前执行&#xff0c;以及在使用之后进行清理时&#xff0c;上下文管理器就非常有用。 例…

926[study]Docker,DHCP

docker与虚拟机&#xff08;VMware&#xff09;的区别&#xff0c;docker基础知识与命令_docker和vmware区别-CSDN博客 .传统的虚拟机是虚拟一整套硬件后&#xff0c;在其运行一个完整的操作系统&#xff0c;而容器内的应用进程直接运行于宿主的内核&#xff0c;容器没有自己的…

【数据结构】手搓链表

一、定义 typedef struct node_s {int _data;struct node_s *_next; } node_t;typedef struct list_s {node_t *_head;node_t *_tail; } list_t;节点结构体&#xff08;node_s&#xff09;&#xff1a; int _data;存储节点中的数据struct node_s *_next;&#xff1a;指向 node…