Spring Boot 中的审计方案选型:不止 JaVers

在 Spring Boot 项目中,"审计"几乎是绕不开的话题:
谁在什么时候,对什么数据,做了什么修改?

很多人第一反应是 JaVers ,也有人提到 Spring Boot 自带的审计接口。但在真实项目中,情况远比文档复杂。

本文将从 Spring Boot 官方能力 → 常见第三方方案 → 企业真实落地方式,系统梳理一套完整的审计方案选型思路。


一、什么是"审计"?先别急着选技术

在选方案前,先明确一点:

审计 ≠ 版本控制

审计通常分为三类:

  1. 字段审计:哪些字段变了
  2. 版本审计:历史快照、回溯
  3. 行为审计:谁做了什么业务动作

不同需求,方案完全不同。


二、Spring Boot 官方提供了什么?

1️⃣ Spring Data JPA Auditing(轻量级)

Spring Data 提供了开箱即用的审计能力,但只覆盖"基础审计字段"

典型能力:

  • 创建时间 / 修改时间
  • 创建人 / 修改人
java 复制代码
@Entity
@EntityListeners(AuditingEntityListener.class)
public class Order {

    @CreatedDate
    private LocalDateTime createdTime;

    @LastModifiedDate
    private LocalDateTime updatedTime;

    @CreatedBy
    private String createdBy;

    @LastModifiedBy
    private String updatedBy;
}

特点总结:

✔ 零侵入

✔ 自动填充

❌ 不记录"改了什么"

❌ 无历史版本

📌 适合:通用业务字段,不适合作为完整审计方案


三、第三方通用审计方案

2️⃣ Hibernate Envers(实体版本审计)

Hibernate 官方提供的审计模块。

java 复制代码
@Audited
@Entity
public class Customer {
    private String name;
    private BigDecimal amount;
}

Envers 会自动生成 _AUD 表,记录实体每次变更的完整快照。

优点:

  • 自动化程度高
  • 无需写业务代码
  • 数据完整可靠

缺点:

  • 表数量膨胀
  • 查询 API 偏底层
  • 无业务语义(只有"改了")

📌 适合:合规性要求高、只关心"历史版本"的系统


3️⃣ JaVers(对象差异审计)

JaVers 更关注 对象快照 + 差异对比

java 复制代码
javers.commit("admin", entity);

可查询:

  • 历史版本
  • 字段差异
  • 提交链路

优点:

  • Diff 可读性强
  • 适合复杂对象
  • 支持 JSON 存储

缺点:

  • 需要显式 commit
  • 查询模型偏技术向
  • UI 展示需要二次封装

📌 适合:需要"字段级变更对比"的系统


四、企业中最常用的方案(重点)

现实中,大部分 Spring Boot 项目,并不会直接用 JaVers / Envers

而是选择下面这种方式。


五、⭐ 主流方案:业务审计表 + AOP(最常见)

核心思想

  • 不自动审计所有实体
  • 只审计关键业务操作
  • 以"业务语义"为中心

常见表结构

sql 复制代码
audit_log
---------
id
biz_type        -- 业务类型(流程 / 合同 / 凭证)
biz_id
action          -- CREATE / UPDATE / SUBMIT / APPROVE
operator_id
operator_name
before_data     -- JSON
after_data      -- JSON
diff_data       -- JSON
created_time

技术实现

  • 自定义 @AuditLog 注解
  • AOP 拦截 Service 层
  • 修改前后对象序列化为 JSON
  • 可选字段级 diff
java 复制代码
@Around("@annotation(AuditLog)")
public Object audit(ProceedingJoinPoint pjp) throws Throwable {
    Object before = loadBeforeData();
    Object result = pjp.proceed();
    Object after = result;
    saveAudit(before, after);
    return result;
}

为什么这是事实上的"标准方案"?

✔ 业务可控

✔ 性能可控

✔ 审计数据"人能看懂"

✔ 易于做审计 UI

📌 OA / ERP / 审批 / 流程系统的首选方案


六、操作日志(行为审计)

很多系统并不关心字段差异,只关心:

谁,在什么时候,做了什么操作

示例:

复制代码
张三 于 2025-01-08 审批了《资金申请单》

技术方式:

  • Controller / Service AOP
  • 请求参数 + 操作结果
  • IP / 用户 / TraceId

📌 流程系统中使用频率极高


七、事件驱动 & 数据库级审计(补充)

事件驱动审计

  • Spring Event
  • MQ(Kafka / RabbitMQ)

适合:

  • 微服务
  • 高并发
  • 审计不影响主事务

数据库级审计

  • Trigger
  • Binlog + Canal

适合:

  • 合规
  • 金融审计
  • 非业务查询场景

八、方案使用率经验排名(真实项目)

排名 方案
🥇 业务审计表 + AOP
🥈 操作日志
🥉 Spring Data JPA Auditing
4️⃣ 自定义字段 Diff
5️⃣ Envers
6️⃣ JaVers

九、推荐组合方案(实战)

在真实项目中,推荐 组合使用

text 复制代码
Spring Data Auditing     → 时间 / 人
AOP 业务审计表           → 行为 & 业务语义
(可选)JaVers           → 关键对象 Diff

这种方案:

  • 可读性强
  • 扩展性好
  • 不"技术绑架"业务

十、总结

Spring Boot 并没有一个"万能审计接口",但提供了良好的基础能力。

选型原则只有一句话:

审计给"人"看,用业务方案;
审计给"系统"看,用技术方案。

相关推荐
栗子叶9 小时前
SSE、长轮询与 WebSocket 连接资源对比及 Spring Boot 配置指南
spring boot·websocket·网络协议
五阿哥永琪9 小时前
Spring boot 在IDEA中如何让一个应用在不同的端口多次启动?
spring boot·后端·intellij-idea
ZePingPingZe9 小时前
SpringMVC与Servlet容器[Tomcat]
spring boot·servlet·tomcat
计算机毕设指导69 小时前
基于微信小程序的精致护肤购物系统【源码文末联系】
java·spring boot·微信小程序·小程序·tomcat·maven·intellij-idea
进阶的小名9 小时前
[超轻量级消息队列(MQ)] Redis 不只是缓存:我用 Redis Stream 实现了一个 MQ(自定义注解方式)
数据库·spring boot·redis·缓存·消息队列·个人开发
何中应9 小时前
@Autowrited和@Resource注解的区别及使用场景
java·开发语言·spring boot·后端·spring
Chan1620 小时前
【 Java八股文面试 | JavaSE篇 】
java·jvm·spring boot·面试·java-ee·八股
FG.21 小时前
LangChain4j
java·spring boot·langchain4j
smileNicky1 天前
SpringBoot系列之集成Pulsar教程
java·spring boot·后端