Spring Boot中审计oldValues的最佳实现方式是什么?
嘿,我之前做项目也碰到过类似的审计需求,纠结过这几个方案,给你梳理下各自的优劣,你可以根据自己的场景来选:
AOP + 自定义@Auditable注解
这个方案的灵活度拉满!你可以给任何需要审计的方法打上@Auditable注解,不管是不是和JPA实体相关的业务方法,都能拦截下来做自定义逻辑。比如你可以在方法调用前先从数据库查一遍旧的实体状态,调用后再和新状态对比,把差异记录下来。不过要注意事务边界的问题,确保拿旧值的时候是在同一个事务里;另外如果有些修改操作绕开了标记注解的方法,就会漏掉审计,得做好代码规范。JPA实体监听器(@EntityListeners)
这个方案和JPA的生命周期绑定得特别紧,用@PreUpdate、@PrePersist这些注解就能精准捕捉实体的增改操作。你可以通过EntityManager获取实体的旧值,或者直接在监听器里对比实体字段的前后变化。优点是代码简洁,和JPA标准兼容,不用依赖特定ORM框架;但缺点也很明显——只能作用在实体类上,非实体的操作没法审计,而且多个实体要审计的话,得抽公共监听器避免重复代码。Hibernate拦截器/事件
这是更底层的方案,能拦截Hibernate所有的持久化操作,不管你是用JPA API还是直接调用Hibernate的API,都能覆盖到。而且能拿到Session级别的底层状态信息,对比旧值更直接。不过它和Hibernate绑定得很深,要是以后换ORM框架就得重构;另外底层API的使用门槛稍高,得熟悉Hibernate的内部机制才行。
给你的小建议:
- 如果你的审计需求不局限于实体操作,还涉及业务方法的审计,果断选AOP +
@Auditable,灵活度最高; - 如果只针对JPA实体的增删改,希望和ORM生命周期紧密结合,选JPA实体监听器就够了,代码更清爽;
- 如果需要全量覆盖Hibernate的所有持久化操作,或者要做一些底层的审计逻辑,那就用Hibernate拦截器/事件。
备注:内容来源于stack exchange,提问作者Mehdi Mhimer

