基于自定义注解与 AOP 切面实现接口日志全面数据库存储
基于自定义注解与 AOP 切面实现接口日志全面数据库存储
一、引言
在当今复杂的软件系统开发与运维过程中,详细且精准地记录接口的各项信息对于系统性能监测、问题排查、安全审计以及业务分析都有着极为关键的意义。本文将深入讲解如何运用自定义注解与 AOP(面向切面编程)技术,全面地将接口的入参信息、出参信息以及接口执行用时记录到数据库中,从而构建一套完善的接口日志管理体系。
二、技术选型与环境搭建
本项目基于 Java 语言开发,采用 Spring Boot 框架搭建应用的基础架构,这有助于快速整合各类组件并实现便捷的开发部署。在数据库层面,选用 MySQL 作为数据存储的后端,以其稳定性和广泛的应用支持来保障日志数据的可靠存储。数据持久化操作借助 MyBatis 框架实现,它能够高效地处理 Java 对象与数据库表之间的映射关系。日志记录方面,依旧以 SLF4J 作为抽象层,结合 Logback 进行灵活的日志打印配置。
三、数据库设计优化
重新设计用于存储接口日志的数据库表,以更好地适应记录入参、出参和执行用时的需求:
CREATE TABLE interface_log (id INT AUTO_INCREMENT PRIMARY KEY,interface_path VARCHAR(255) NOT NULL,invocation_time TIMESTAMP NOT NULL,user_info VARCHAR(255),input_parameters VARCHAR(255),output_parameters VARCHAR(255),execution_time BIGINT,description VARCHAR(255)
);
新增的 execution_time
字段用于存储接口执行所耗费的时间,单位为毫秒,以便后续对接口性能进行分析评估。
四、自定义注解设计
定义 LoggableFullDB
自定义注解,用于明确需要进行全面日志记录到数据库的接口方法:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoggableFullDB {String value() default "";
}
五、AOP 切面实现升级
构建更为完善的 AOP 切面类 LoggingAspectFullDB
,负责精确地拦截被 LoggableFullDB
注解标记的方法,并全面地记录接口相关信息到数据库:
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Date;@Aspect
@Component
public class LoggingAspectFullDB {private static final Logger logger = LoggerFactory.getLogger(LoggingAspectFullDB.class);// 在方法执行前记录相关信息并准备插入数据库的数据@Before("@annotation(loggableFullDB)")public void beforeMethodExecution(JoinPoint joinPoint, LoggableFullDB loggableFullDB) {ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getServletRequest();InterfaceLogDTO logDTO = new InterfaceLogDTO();// 记录接口路径地址logDTO.setInterfacePath(request.getRequestURI());// 记录调用时间logDTO.setInvocationTime(new Date());// 尝试获取用户信息(假设用户信息存储在请求头中的某个字段,可根据实际情况修改)logDTO.setUserInfo(request.getHeader("user"));// 记录方法参数logDTO.setInputParameters(Arrays.toString(joinPoint.getArgs()));logDTO.setDescription(loggableFullDB.value());// 记录方法开始执行时间,用于后续计算执行用时logDTO.setStartTime(System.currentTimeMillis());// 此处可将 logDTO 传递给数据库操作层进行插入操作的准备,例如调用 service 层方法logService.prepareLogInsert(logDTO);}// 在方法执行成功返回后记录出参信息并完成数据库插入操作@AfterReturning(pointcut = "@annotation(loggableFullDB)", returning = "result")public void afterMethodExecution(JoinPoint joinPoint, LoggableFullDB loggableFullDB, Object result) {InterfaceLogDTO logDTO = logService.getLogDTOForUpdate(); // 获取之前准备的 logDTO// 记录返回结果logDTO.setOutputParameters(result.toString());// 计算接口执行用时并存储long endTime = System.currentTimeMillis();logDTO.setExecutionTime(endTime - logDTO.getStartTime());// 执行数据库插入操作logService.insertLog(logDTO);}
}
其中 InterfaceLogDTO
数据传输对象也相应地更新:
public class InterfaceLogDTO {private String interfacePath;private Date invocationTime;private String userInfo;private String inputParameters;private String outputParameters;private Long executionTime;private Long startTime;private String description;// 省略 getter 和 setter 方法
}
六、数据库操作层实现优化
优化 LogService
接口及其实现类 LogServiceImpl
,确保与新的日志记录需求和数据库表结构相适配:
public interface LogService {void prepareLogInsert(InterfaceLogDTO logDTO);InterfaceLogDTO getLogDTOForUpdate();void insertLog(InterfaceLogDTO logDTO);
}
import org.springframework.stereotype.Service;@Service
public class LogServiceImpl implements LogService {private ThreadLocal<InterfaceLogDTO> logDTOLocal = new ThreadLocal<>();@Overridepublic void prepareLogInsert(InterfaceLogDTO logDTO) {logDTOLocal.set(logDTO);}@Overridepublic InterfaceLogDTO getLogDTOForUpdate() {return logDTOLocal.get();}@Overridepublic void insertLog(InterfaceLogDTO logDTO) {// 使用 MyBatis 或其他数据库操作工具将 logDTO 中的数据插入到数据库表中// 这里省略具体的数据库插入代码,例如:sqlSession.insert("insertInterfaceLog", logDTO);logDTOLocal.remove();}
}
七、在接口中应用自定义注解
在具体的接口方法上应用 LoggableFullDB
注解,如下示例:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class OrderController {@LoggableFullDB("获取订单详情接口")@GetMapping("/order/details")public Order getOrderDetails(String orderId) {// 模拟获取订单详情的业务逻辑Order order = new Order();order.setId(orderId);order.setCustomerName("John Doe");order.setTotalAmount(100.0);return order;}
}
八、日志打印配置
在 application.properties
或 application.yml
文件中配置 Logback 进行日志打印输出:
# Logback 配置
logging:level:root: INFOpattern:console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
九、总结
通过精心设计的自定义注解、强大的 AOP 切面技术以及完善的数据库操作层构建,我们成功实现了接口日志的全面数据库存储方案。该方案能够精确地记录接口的入参信息、出参信息以及执行用时,并将这些关键数据可靠地存储到数据库中。这不仅为系统的运维监控提供了丰富且准确的数据依据,也为后续的业务分析和性能优化奠定了坚实的基础。在实际项目应用中,可依据具体业务场景和需求进一步对数据库表结构、日志记录策略以及数据处理流程进行深度优化与扩展,以实现更为高效和智能的接口日志管理系统。
相关文章:
基于自定义注解与 AOP 切面实现接口日志全面数据库存储
基于自定义注解与 AOP 切面实现接口日志全面数据库存储 一、引言 在当今复杂的软件系统开发与运维过程中,详细且精准地记录接口的各项信息对于系统性能监测、问题排查、安全审计以及业务分析都有着极为关键的意义。本文将深入讲解如何运用自定义注解与 AOP&#x…...
GraalVM完全指南:云原生时代下使用GraalVM将Spring Boot 3应用转换为高效Linux可执行文件
一、前言 在现代软件开发中,启动速度和资源利用率常常是衡量应用性能的关键指标。对于基于Spring Boot的应用来说,虽然它们易于开发和部署,但JVM的启动时间有时会成为一个瓶颈。本文介绍如何使用GraalVM将Spring Boot 3应用编译成原生Linux可执行文件,从而显著提高启动速度…...

单片机:实现驱动超声波(附带源码)
单片机实现驱动超声波模块 超声波模块(如HC-SR04)广泛应用于距离测量、避障系统、自动驾驶等嵌入式项目中。它能够通过发射超声波信号并接收反射波来计算物体的距离。本文将介绍如何使用单片机(如51系列单片机)驱动超声波模块&am…...
2025.01.15python商业数据分析top2
一、 导入项目 导入项目、准备项目数据 import pandas as pd# 文件路径为python文件位置下的相对路径dwxpd.read_excel("电蚊香套装市场近三年交易额.xlsx") fmfzpd.read_excel("防霉防蛀片市场近三年交易额.xlsx") msmcpd.read_excel("灭鼠杀虫剂市…...
信息系统项目管理-绩效考核
1.1.组织战略 组织的产品和服务战略的类型通常可以分为:技术密集型、()、目标动态型。 A市场导向型 B成本导向型 C人力密集型 D产品导向型 答案B 在组织的四项基本能力中,建立战略性奖励措施,根据员工对组织的贡献&am…...
【Linux】数据呈现
一、数据的输入与输出 1、标准文件描述符 Linux系统会将每个对象都当做文件来处理,包括输入和输出。它用文件描述符来标识每个文件对象。 文件描述符是一个非负整数,唯一会标识的是会话中打开的文件。每个进程一次最多可以打开9个文件描述符。bash sh…...
oracle 加字段和字段注释 sql
在 Oracle 数据库中,你可以使用 ALTER TABLE 语句来添加字段,并使用 COMMENT ON COLUMN 语句来添加字段注释。以下是一个示例: 假设你有一个名为 employees 的表,你想要添加一个名为 email 的字段,并为其添加注释。 …...

计算机网络压缩版
计算机网络到现在零零散散也算过了三遍,一些协议大概了解,但总是模模糊糊的印象,现在把自己的整体认识总结一下,(本来想去起名叫《看这一篇就够了》,但是发现网上好的文章太多了,还是看这篇吧&a…...
一文了解 gis 相关服务=》及前端地图服务相关总结
文章目录 概要OGC技术名词解释cesium 应用案例openlayers 中应用实例XYZ服务OSM服务WMS服务WMTS服务WFS服务 mapbox 应用实例矢量瓦片服务栅格瓦片服务WMS服务WFS服务 leaflet 中 地图服务实例加载OpenStreetMap瓦片图层加载自定义XYZ瓦片图层加载WMS服务图层加载WFS服务图层加…...
Brocade G610 配置
配置流程 zone创建–>cfg创建–>ip配置–>cfg启动并保存 查看端口信息 G610:admin> switchshow switchName: G610 switchType: 170.5 switchState: Online switchMode: Native switchRole: Principal switchDomain: 1 switchId: ff…...
DuetWebControl 开源项目常见问题解决方案
DuetWebControl 开源项目常见问题解决方案 DuetWebControl A completely new web interface for the Duet electronics [这里是图片001] 项目地址: https://gitcode.com/gh_mirrors/du/DuetWebControl 一、项目基础介绍 DuetWebControl 是一个为 RepRapFirmware 设计的完全响…...

亚信安全举办“判大势 悟思想 强实践”主题党日活动
为深入学习和贯彻党的二十届三中全会精神,近日,亚信安全举办了 “学习贯彻党的二十届三中全会精神——‘判大势 悟思想 强实践’党日活动”,并取得圆满成功。 本次活动特邀南京市委宣讲团成员、南京市委党校市情研究中心主任王辉龙教授出席。…...

Go怎么做性能优化工具篇之基准测试
一、什么是基准测试(Benchmark) 在 Go 中,基准测试是通过创建以 Benchmark 开头的函数,并接收一个 *testing.B 类型的参数来实现的。testing.B 提供了控制基准测试执行的接口,比如设置测试执行的次数、记录每次执行的…...

vue3国际化,主题切换
国际化 安装依赖 pnpm install i18n pnpm install vue-i18n main.js import { createApp } from vue import App from ./App.vue import { i18n } from /i18n/index; const app createApp(App) app.use(i18n); app.mount(#app) 根目录创建i18n文件夹,创建3个文件&…...

Linux Shell 脚本编程基础
打开kali,Xshell连接 一、 vim 1.sh 可利用 #! /bin/bash, #! /bin/dash ,#! bin/sh 这三种脚本解释器不论哪种,最终都是调用 dash 在1.sh内加入内容,尝试执行,./1.sh,但需要加权 或者,在不使用加权的情…...
vuex如何进行状态管理?
**Vuex:是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间数据共享。** (1) 如果是Vue2的环境,不能使用vuex4的版本,所以我们需要安装vuex3以下的版本安装。 创建项目:vue crea…...

嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目
此项目是基于人脸识别的考勤系统开发,包括如下模块: 1、人脸识别考勤系统GUI界面设计,包括: (1)Qt环境(window环境/linux环境) ; (2)Qt工程创建分析; &am…...

通过阿里云 Milvus 与 PAI 搭建高效的检索增强对话系统
背景介绍 阿里云向量检索服务Milvus版(简称阿里云Milvus)是一款云上全托管服务,确保了了与开源Milvus的100%兼容性,并支持无缝迁移。在开源版本的基础上增强了可扩展性,能提供大规模 AI 向量数据的相似性检索服务。相…...

评估大语言模型在药物基因组学问答任务中的表现:PGxQA
这篇文献主要介绍了一个名为PGxQA的资源,用于评估大语言模型(LLM)在药物基因组学问答任务中的表现。 研究背景 药物基因组学(Pharmacogenomics, PGx)是精准医学中最有前景的领域之一,通过基因指导的治疗…...

在本地和远程转储域控制器哈希
更多内网知识课前往无问社区查看http://www.wwlib.cn 无凭据 - ntdsutil 如果您没有凭据,但有权访问 DC,则可以使用 lolbin ntdsutil.exe转储 ntds.dit: powershell "ntdsutil.exe ac i ntds ifm create full c:\temp q q" 我们…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...

练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

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 的密码…...