基于自界说注解与 AOP 切面实现接口日记全面数据库存储

[复制链接]
发表于 2025-11-23 19:54:50 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
基于自界说注解与 AOP 切面实现接口日记全面数据库存储

一、弁言

在当今复杂的软件体系开发与运维过程中,详细且精准地记载接口的各项信息对于体系性能监测、标题排查、安全审计以及业务分析都有着极为关键的意义。本文将深入解说怎样运用自界说注解与 AOP(面向切面编程)技能,全面地将接口的入参信息、出参信息以及接口实验用时记载到数据库中,从而构建一套美满的接口日记管理体系。
二、技能选型与情况搭建

本项目基于 Java 语言开发,采取 Spring Boot 框架搭建应用的根本架构,这有助于快速整合各类组件并实现便捷的开发摆设。在数据库层面,选用 MySQL 作为数据存储的后端,以其稳固性和广泛的应用支持来保障日记数据的可靠存储。数据恒久化操纵借助 MyBatis 框架实现,它可以或许高效地处理惩罚 Java 对象与数据库表之间的映射关系。日记记载方面,仍旧以 SLF4J 作为抽象层,联合 Logback 举行机动的日记打印设置。
三、数据库计划优化

重新计划用于存储接口日记的数据库表,以更好地顺应记载入参、出参和实验用时的需求:
  1. CREATE TABLE interface_log (
  2.     id INT AUTO_INCREMENT PRIMARY KEY,
  3.     interface_path VARCHAR(255) NOT NULL,
  4.     invocation_time TIMESTAMP NOT NULL,
  5.     user_info VARCHAR(255),
  6.     input_parameters VARCHAR(255),
  7.     output_parameters VARCHAR(255),
  8.     execution_time BIGINT,
  9.     description VARCHAR(255)
  10. );
复制代码
新增的 execution_time 字段用于存储接口实验所淹灭的时间,单元为毫秒,以便后续对接口性能举行分析评估。
四、自界说注解计划

界说 LoggableFullDB 自界说注解,用于明白必要举行全面日记记载到数据库的接口方法:
  1. import java.lang.annotation.ElementType;
  2. import java.lang.annotation.Retention;
  3. import java.lang.annotation.RetentionPolicy;
  4. import java.lang.annotation.Target;
  5. @Target(ElementType.METHOD)
  6. @Retention(RetentionPolicy.RUNTIME)
  7. public @interface LoggableFullDB {
  8.     String value() default "";
  9. }
复制代码
五、AOP 切面实现升级

构建更为美满的 AOP 切面类 LoggingAspectFullDB,负责正确地拦截被 LoggableFullDB 注解标记的方法,并全面地记载接口干系信息到数据库:
  1. import org.aspectj.lang.JoinPoint;
  2. import org.aspectj.lang.annotation.AfterReturning;
  3. import org.aspectj.lang.annotation.Aspect;
  4. import org.aspectj.lang.annotation.Before;
  5. import org.slf4j.Logger;
  6. import org.slf4j.LoggerFactory;
  7. import org.springframework.stereotype.Component;
  8. import org.springframework.web.context.request.RequestContextHolder;
  9. import org.springframework.web.context.request.ServletRequestAttributes;
  10. import javax.servlet.http.HttpServletRequest;
  11. import java.util.Arrays;
  12. import java.util.Date;
  13. @Aspect
  14. @Component
  15. public class LoggingAspectFullDB {
  16.     private static final Logger logger = LoggerFactory.getLogger(LoggingAspectFullDB.class);
  17.     // 在方法执行前记录相关信息并准备插入数据库的数据
  18.     @Before("@annotation(loggableFullDB)")
  19.     public void beforeMethodExecution(JoinPoint joinPoint, LoggableFullDB loggableFullDB) {
  20.         ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  21.         HttpServletRequest request = attributes.getServletRequest();
  22.         InterfaceLogDTO logDTO = new InterfaceLogDTO();
  23.         // 记录接口路径地址
  24.         logDTO.setInterfacePath(request.getRequestURI());
  25.         // 记录调用时间
  26.         logDTO.setInvocationTime(new Date());
  27.         // 尝试获取用户信息(假设用户信息存储在请求头中的某个字段,可根据实际情况修改)
  28.         logDTO.setUserInfo(request.getHeader("user"));
  29.         // 记录方法参数
  30.         logDTO.setInputParameters(Arrays.toString(joinPoint.getArgs()));
  31.         logDTO.setDescription(loggableFullDB.value());
  32.         // 记录方法开始执行时间,用于后续计算执行用时
  33.         logDTO.setStartTime(System.currentTimeMillis());
  34.         // 此处可将 logDTO 传递给数据库操作层进行插入操作的准备,例如调用 service 层方法
  35.         logService.prepareLogInsert(logDTO);
  36.     }
  37.     // 在方法执行成功返回后记录出参信息并完成数据库插入操作
  38.     @AfterReturning(pointcut = "@annotation(loggableFullDB)", returning = "result")
  39.     public void afterMethodExecution(JoinPoint joinPoint, LoggableFullDB loggableFullDB, Object result) {
  40.         InterfaceLogDTO logDTO = logService.getLogDTOForUpdate(); // 获取之前准备的 logDTO
  41.         // 记录返回结果
  42.         logDTO.setOutputParameters(result.toString());
  43.         // 计算接口执行用时并存储
  44.         long endTime = System.currentTimeMillis();
  45.         logDTO.setExecutionTime(endTime - logDTO.getStartTime());
  46.         // 执行数据库插入操作
  47.         logService.insertLog(logDTO);
  48.     }
  49. }
复制代码
此中 InterfaceLogDTO 数据传输对象也相应地更新:
  1. public class InterfaceLogDTO {
  2.     private String interfacePath;
  3.     private Date invocationTime;
  4.     private String userInfo;
  5.     private String inputParameters;
  6.     private String outputParameters;
  7.     private Long executionTime;
  8.     private Long startTime;
  9.     private String description;
  10.     // 省略 getter 和 setter 方法
  11. }
复制代码
六、数据库操纵层实现优化

优化 LogService 接口及着实现类 LogServiceImpl,确保与新的日记记载需求和数据库表布局相适配:
  1. public interface LogService {
  2.     void prepareLogInsert(InterfaceLogDTO logDTO);
  3.     InterfaceLogDTO getLogDTOForUpdate();
  4.     void insertLog(InterfaceLogDTO logDTO);
  5. }
复制代码
  1. import org.springframework.stereotype.Service;
  2. @Service
  3. public class LogServiceImpl implements LogService {
  4.     private ThreadLocal<InterfaceLogDTO> logDTOLocal = new ThreadLocal<>();
  5.     @Override
  6.     public void prepareLogInsert(InterfaceLogDTO logDTO) {
  7.         logDTOLocal.set(logDTO);
  8.     }
  9.     @Override
  10.     public InterfaceLogDTO getLogDTOForUpdate() {
  11.         return logDTOLocal.get();
  12.     }
  13.     @Override
  14.     public void insertLog(InterfaceLogDTO logDTO) {
  15.         // 使用 MyBatis 或其他数据库操作工具将 logDTO 中的数据插入到数据库表中
  16.         // 这里省略具体的数据库插入代码,例如:sqlSession.insert("insertInterfaceLog", logDTO);
  17.         logDTOLocal.remove();
  18.     }
  19. }
复制代码
七、在接口中应用自界说注解

在详细的接口方法上应用 LoggableFullDB 注解,如下示例:
  1. import org.springframework.web.bind.annotation.GetMapping;
  2. import org.springframework.web.bind.annotation.RestController;
  3. @RestController
  4. public class OrderController {
  5.     @LoggableFullDB("获取订单详情接口")
  6.     @GetMapping("/order/details")
  7.     public Order getOrderDetails(String orderId) {
  8.         // 模拟获取订单详情的业务逻辑
  9.         Order order = new Order();
  10.         order.setId(orderId);
  11.         order.setCustomerName("John Doe");
  12.         order.setTotalAmount(100.0);
  13.         return order;
  14.     }
  15. }
复制代码
八、日记打印设置

在 application.properties 或 application.yml 文件中设置 Logback 举行日记打印输出:
  1. # Logback 配置
  2. logging:
  3.   level:
  4.     root: INFO
  5.   pattern:
  6.     console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n"
复制代码
九、总结

通过经心计划的自界说注解、强盛的 AOP 切面技能以及美满的数据库操纵层构建,我们乐成实现了接口日记的全面数据库存储方案。该方案可以或许正确地记载接口的入参信息、出参信息以及实验用时,并将这些关键数据可靠地存储到数据库中。这不但为体系的运维监控监控提供了丰富且正确的数据依据,也为后续的业务分析和性能优化奠定告终实的根本。在实际项目应用中,可依据详细业务场景和需求进一步对数据库表布局、日记记载战略以及数据处理惩罚流程举行深度优化与扩展,以实现更为高效和智能的接口日记管理体系。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表