Java实战:Spring Boot实现AOP记录操作日志
本文将详细介绍如何在Spring Boot应用程序中使用Aspect Oriented Programming(AOP)来实现记录操作日志的功能。我们将探讨Spring Boot集成AOP的基本概念,以及如何使用Spring Boot实现AOP记录操作日志。最后,我们将通过一个具体示例来演示整个实现过程。本文适合已经具备Spring Boot基础知识的开发者阅读,以加深对Spring Boot中AOP记录操作日志的理解。
一、引言
在开发Web应用程序时,记录操作日志是一项非常重要的功能。它可以帮助我们跟踪用户的行为,监控应用程序的运行状态,以及为后续的问题排查和数据分析提供依据。在传统的Spring应用程序中,记录操作日志通常需要在每个Controller或Service方法中手动添加日志记录代码。这种方法不仅代码冗余,而且难以维护。为了解决这个问题,我们可以使用Spring Boot集成Aspect Oriented Programming(AOP)来实现记录操作日志的功能。
二、Spring Boot集成AOP的基本概念
1. 什么是AOP?
AOP(Aspect Oriented Programming,面向切面编程)是一种编程范式,它允许开发者定义跨多个对象的操作。AOP的核心思想是将应用程序的逻辑分为两个部分:核心业务逻辑(称为“横切关注点”)和横切逻辑(称为“切面”)。通过使用AOP,我们可以将横切关注点与核心业务逻辑分离,从而提高代码的可重用性和可维护性。
2. 如何在Spring Boot中集成AOP?
Spring Boot支持使用AspectJ作为其AOP实现。要集成AOP,我们需要在项目中添加Spring Boot AOP依赖,并创建一个切面类来实现日志记录功能。
三、Spring Boot实现AOP记录操作日志
1. 添加AOP依赖
在项目的pom.xml文件中,添加Spring Boot AOP依赖:
<dependencies><!-- Spring Boot Web依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Boot AOP依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><!-- MySQL驱动依赖 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency>
</dependencies>
2. 创建切面类
创建一个切面类,用于实现日志记录功能。以下是一个简单的切面类示例:
package com.example.demo.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LogAspect {@Before("execution(* com.example.demo.controller..*.*(..))")public void beforeMethod(JoinPoint joinPoint) {System.out.println("Before method: " + joinPoint.getSignature().getName());}@After("execution(* com.example.demo.controller..*.*(..))")public void afterMethod(JoinPoint joinPoint) {System.out.println("After method: " + joinPoint.getSignature().getName());}
}
在上面的代码中,我们定义了两个通知(advice):beforeMethod和afterMethod。这些通知将在执行指定包下的所有方法之前和之后运行。我们使用了JoinPoint对象来获取方法名,以便在日志中打印。
3. 创建日志实体类
创建一个日志实体类,用于表示操作日志。以下是一个简单的日志实体类示例:
package com.example.demo.entity;
import java.util.Date;
public class Log {private Long id;private String username;private String operation;private Date createTime;private Date updateTime;// getter和setter方法
}
4. 创建日志服务类
创建一个日志服务类,用于实现日志的增删改查功能。以下是一个简单的日志服务类示例:
package com.example.demo.service;
import com.example.demo.entity.Log;
import com.example.demo.repository.LogRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class LogService {@Autowiredprivate LogRepository logRepository;public void addLog(Log log) {logRepository.save(log);}public List<Log> getAllLogs() {return logRepository.findAll();}public Log getLogById(Long id) {return logRepository.findById(id).orElse(null);}public void updateLog(Log log) {logRepository.save(log);}public void deleteLog(Long id) {logRepository.deleteById(id);}
}
5. 创建日志仓库接口
创建一个日志仓库接口,用于定义日志的JPA操作。以下是一个简单的日志仓库接口示例:
package com.example.demo.repository;
import com.example.demo.entity.Log;
import org.springframework.data.jpa.repository.JpaRepository;
public interface LogRepository extends JpaRepository<Log, Long> {
}
6. 创建Controller类
创建一个Controller类,用于处理操作日志的HTTP请求。以下是一个简单的Controller类示例:
package com.example.demo.controller;
import com.example.demo.entity.Log;
import com.example.demo.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/log")
public class LogController {@Autowiredprivate LogService logService;@PostMapping("/add")public String addLog(@RequestBody Log log) {logService.addLog(log);return "Log added successfully";}@GetMapping("/getAll")public List<Log> getAllLogs() {return logService.getAllLogs();}@GetMapping("/getById/{id}")public Log getLogById(@PathVariable Long id) {return logService.getLogById(id);}@PutMapping("/update")public String updateLog(@RequestBody Log log) {logService.updateLog(log);return "Log updated successfully";}@DeleteMapping("/delete/{id}")public String deleteLog(@PathVariable Long id) {logService.deleteLog(id);return "Log deleted successfully";}
}
7. 运行项目
将以上代码添加到我们的Spring Boot项目中,并运行项目。我们可以使用Postman或curl工具向http://localhost:8080/log/add发送POST请求,以添加操作日志。同时,我们还可以访问其他API接口来测试日志的查询、更新和删除功能。
四、总结
本文详细介绍了如何在Spring Boot应用程序中使用AOP来实现记录操作日志的功能。我们首先了解了Spring Boot集成AOP的基本概念,然后学习了如何使用Spring Boot实现AOP记录操作日志。最后,我们通过一个具体示例演示了如何在Spring Boot应用程序中实现AOP记录操作日志。
通过本文,您应该已经掌握了如何在Spring Boot中使用AOP来实现操作日志的记录。这种方法不仅代码简洁,而且易于维护和扩展。希望本文能够帮助您在开发Spring Boot应用程序时更加得心应手。如果您有任何疑问或建议,请随时留言交流。
相关文章:
Java实战:Spring Boot实现AOP记录操作日志
本文将详细介绍如何在Spring Boot应用程序中使用Aspect Oriented Programming(AOP)来实现记录操作日志的功能。我们将探讨Spring Boot集成AOP的基本概念,以及如何使用Spring Boot实现AOP记录操作日志。最后,我们将通过一个具体示例…...
C++ //练习 7.38 有些情况下我们希望提供cin作为接受istream参数的构造函数的默认实参,请声明这样的构造函数。
C Primer(第5版) 练习 7.38 练习 7.38 有些情况下我们希望提供cin作为接受istream&参数的构造函数的默认实参,请声明这样的构造函数。 环境:Linux Ubuntu(云服务器) 工具:vim 代码块 Sa…...
算法:两数之和
算法:两数之和 方法一:暴力法 function twoSum(nums, target) {for (let i 0; i < nums.length; i) {for (let j i 1; j < nums.length; j) {if (nums[i] nums[j] target) {return [i, j];}}}return null; }方法二:哈希表 func…...
pytorch: ground truth similarity matrix
按照真实标签排序pair-wise相似度矩阵的Pytorch代码 本文仅作留档,用于输出可视化 Inputs: Ground-truths Y ∈ R n 1 \mathbf{Y}\in\mathbb R^{n\times 1} Y∈Rn1, Similarity matrix A ∈ R n n \mathbf{A}\in\mathbb R^{n\times n} A∈RnnOutputs: Block dia…...
鸿蒙 gnss 开关使能流程
先WiFi,后 定位,再从蓝牙到NFC,这个就是我大致熟悉开源鸿蒙代码的一个顺序流程,WiFi 的年前差不多基本流程熟悉了,当然还有很多细节和内容没有写到,后续都会慢慢的丰富起来,这一篇将开启GNSS的篇…...
设计模式-创建型模式-抽象工厂模式
抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。 由于工厂方法模式中的每个工厂只生产一类产品&…...
【Go】五、Grpc 的入门使用
grpc 与 protobuf grpc 使用的是 protobuf 协议,其是一个通用的 rpc 框架,基本支持主流的所有语言、其底层使用 http/2 进行网络通信,具有较高的效率 protobuf 是一种序列化格式,这种格式具有 序列化以及解码速度快(…...
PDF加粗内容重复读取解决方案
文章目录 前言发现问题解决方案问题分析大致逻辑 show my code 前言 在使用pdfplumber读取PDF的过程中,由于加黑的内容会被莫名其妙的读取两次,带来了很大的困扰。这篇文章将给出解决方案。 发现问题 在在使用pdfplumber读取PDF的过程中,读…...
Golang 并发 Channel的用法
目录 Golang 并发 Channel的用法1. channel 的创建2. nil channel读写阻塞示例close示例 3. channel 的读写4. channel 只读只写5. 关闭channelchannel关闭后,剩余的数据能否取到读取关闭的channel,将获取零值使用ok判断,是否关闭使用for-ran…...
cfa复习资料介绍之二:notes(SchweserNotes)
什么是CFA notes? CFA资料Study Notes都是外国一些出版机构针对CFA考试提供的复习资料,而其中Schweser在国内的名气最大,用的人也最多。内容详尽并且突出重点,并且CFA Notes的内容相比于官方curriculum教材更加符合中国CFA考生的心态&#x…...
FITC Palmitate Conjugate,FITC-棕榈酸酯缀合物,可以用标准 FITC 滤光片组进行成像
FITC Palmitate Conjugate,FITC-棕榈酸酯缀合物,可以用标准 FITC 滤光片组进行成像 您好,欢迎来到新研之家 文章关键词:FITC Palmitate Conjugate,FITC-棕榈酸酯缀合物,FITC 棕榈酸酯缀合物,F…...
本机防攻击简介
定义 在网络中,存在着大量针对CPU(Central Processing Unit)的恶意攻击报文以及需要正常上送CPU的各类报文。针对CPU的恶意攻击报文会导致CPU长时间繁忙的处理攻击报文,从而引发其他业务的中断甚至系统的中断;大量正常…...
Python 进阶语法:JSON
1 什么是 JSON? 1.1 JSON 的定义 JSON 是 JavaScript Object Notation 的简写,字面上的意思是 JavaScript 对象标记。本质上,JSON 是轻量级的文本数据交换格式。轻量级,是拿它与另一种数据交换格式XML进行比较,相当轻…...
mescroll 在uni-app 运行的下拉刷新和上拉加载的组件
官网传送门: https://www.mescroll.com/uni.html 最近使用到了mescroll 但是一直都是整个页面的滚动, 最近需求有需要局部滚动, 收藏了一个博主的文章觉得写的还挺好, 传送门: https://blog.csdn.net/Minions_Fatman/article/details/134754926?spm1001.2014.3001.5506 使用…...
netty的TCP服务端和客户端实现
第一步:引入依赖 <dependencies><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.90.Final</version></dependency></dependencies> 第二步:实…...
合纵连横 – 以 Flink 和 Amazon MSK 构建 Amazon DocumentDB 之间的实时数据同步
在大数据时代,实时数据同步已经有很多地方应用,包括从在线数据库构建实时数据仓库,跨区域数据复制。行业落地场景众多,例如,电商 GMV 数据实时统计,用户行为分析,广告投放效果实时追踪ÿ…...
HBase 进阶
参考来源: B站尚硅谷HBase2.x 目录 Master 架构RegionServer 架构写流程MemStore Flush读流程HFile 结构读流程合并读取数据优化 StoreFile CompactionRegion Split预分区(自定义分区)系统拆分 Master 架构 Master详细架构 1)Meta 表格介…...
一周学会Django5 Python Web开发-Django5路由命名与反向解析reverse与resolve
锋哥原创的Python Web开发 Django5视频教程: 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计25条视频,包括:2024版 Django5 Python we…...
好奇!为什么gateway和springMVC之间依赖冲突?
Gateway和SpringMVC之间存在冲突,可能是因为它们分别基于不同的技术栈。具体来说: 技术栈差异:Spring Cloud Gateway 是建立在 Spring Boot 2.x 和 Spring WebFlux 基础之上的,它使用的是非阻塞式的 Netty 服务器。而 Spring MVC…...
一些内网渗透总结
windows命令收集 信息收集: 查看系统版本和补丁信息: systeminfo 查看系统开放端口: netstat -ano 查看系统进程: tasklist /svc 列出详细进程: tasklist /V /FO CSV 查看ip地址和dns信息: ipconfig /all 查看当前用户: whoami /user 查看计算机用户列表: net user 查看计算机…...
【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...
uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...
【Veristand】Veristand环境安装教程-Linux RT / Windows
首先声明,此教程是针对Simulink编译模型并导入Veristand中编写的,同时需要注意的是老用户编译可能用的是Veristand Model Framework,那个是历史版本,且NI不会再维护,新版本编译支持为VeriStand Model Generation Suppo…...
渗透实战PortSwigger Labs指南:自定义标签XSS和SVG XSS利用
阻止除自定义标签之外的所有标签 先输入一些标签测试,说是全部标签都被禁了 除了自定义的 自定义<my-tag onmouseoveralert(xss)> <my-tag idx onfocusalert(document.cookie) tabindex1> onfocus 当元素获得焦点时(如通过点击或键盘导航&…...
