common-audit 字段审计使用
什么是字段审计
在后台开发中,一般的业务表都会包含一些审计记录的字段,例如创建人、创建时间、修改人和修改时间等。这些字段只是记录当时的操作人和操作时间,没有特别的逻辑。
对于个别敏感字段,需要记录其变更前后的数据值。比如,如果修改前是 A,修改后是 B,则需要将这些操作记录到数据库中,以便日后进行审计。
添加依赖
<!-- 字段审计 -->
<dependency>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-audit</artifactId>
</dependency>
实体字段标记审计
在需要审计的字段上添加 @DiffInclude 和 @PropertyName 注解:
public class SysUser implements Serializable {
@DiffInclude
@PropertyName("手机号")
private String phone;
}
💡注解说明
@DiffInclude 标记字段需要审计,@PropertyName 指定字段的显示名称
业务层添加审计
在需要审计的业务方法上添加 @Audit 注解:
public Boolean updateUser(UserDTO userDto) {
// 业务逻辑
return Boolean.TRUE;
}
在上述业务层中,userDto 是前端更新后的数据。如果要进行审计,需要获取原有数据。
方法一: 使用 Spring SpEL 表达式(推荐)
@Audit(name = "用户更新", spel = "@sysUserMapper.selectById(#userDto.userId)")
表达式解析:
@sysUserMapper: 获取名称为 sysUserMapper 的 Bean
selectById: 调用 selectById 方法
#userDto.userId: 方法参数来自于当前方法(service.updateUser)的 userDto 的 userId 字段
方法二: 直接指定原值(写死)
@Audit(name = "用户更新", oldVal = "17034642449")
⚠方法二局限性
直接写死原值不够灵活,仅适用于特殊测试场景,生产环境建议使用 SpEL 表达式
@Audit 注解属性说明
| 属性 | 解释 |
|---|
| name | 审计项名称 |
| value / spel | 表达式语言,用于生成审计信息 |
| oldVal | 修改前的值(覆盖 spel 的结果) |
| newVal | 修改后的值(覆盖 service 方法的执行结果) |
常见问题
⚠为什么我自己的方法不记录
audit 基于 Spring AOP,请务必明确知悉 Spring AOP 的触发条件,尤其需要注意同类内部方法调用(方法嵌套)不会触发代理,否则将导致 AOP 失效,进而使审计逻辑无法生效。
AOP 生效条件示例
// 业务类
class Service {
@Audit
methodA() {
// AOP 生效
doSomething()
}
methodB() {
// 同类内部调用
// 不经过代理,AOP 不生效
methodA()
}
}
// 正确调用方式
class Controller {
Service service
call() {
// 通过 Spring 容器代理调用
// AOP 生效
service.methodA()
}
}
💡最佳实践
审计方法应该由外部调用者(如 Controller)直接调用,避免在同一个类内部进行方法嵌套调用