如何在Quarkus框架中实现类似JPA Auditing的功能?
在Quarkus中实现JPA审计功能
如果你想实现类似Spring Data JPA中@CreatedBy/@CreatedDate的审计功能,Quarkus可以通过自定义实体监听器+CDI依赖注入来实现,具体步骤如下:
1. 定义审计基础实体类
创建一个映射超类,包含审计所需的字段,所有需要审计的实体都继承这个类:
@MappedSuperclass @EntityListeners(AuditEntityListener.class) public abstract class EntityAuditInfo { @Column(name = "created_by", nullable = false) private Integer createdBy; @Column(name = "created_on", nullable = false) private LocalDateTime createdOn; @Column(name = "modified_by") private Integer modifiedBy; @Column(name = "modified_on") private LocalDateTime modifiedOn; // Getter和Setter方法 public Integer getCreatedBy() { return createdBy; } public void setCreatedBy(Integer createdBy) { this.createdBy = createdBy; } public LocalDateTime getCreatedOn() { return createdOn; } public void setCreatedOn(LocalDateTime createdOn) { this.createdOn = createdOn; } public Integer getModifiedBy() { return modifiedBy; } public void setModifiedBy(Integer modifiedBy) { this.modifiedBy = modifiedBy; } public LocalDateTime getModifiedOn() { return modifiedOn; } public void setModifiedOn(LocalDateTime modifiedOn) { this.modifiedOn = modifiedOn; } }
2. 实现自定义实体监听器
创建一个CDI管理的实体监听器,利用JPA的@PrePersist和@PreUpdate注解,在实体持久化和更新前自动填充审计字段:
@ApplicationScoped public class AuditEntityListener { @Inject CurrentUserService currentUserService; @Inject Clock clock; // 实体首次保存前触发 @PrePersist public void prePersist(EntityAuditInfo entity) { Integer currentUserId = currentUserService.getCurrentUserId(); entity.setCreatedBy(currentUserId); entity.setCreatedOn(LocalDateTime.now(clock)); // 首次保存时同时初始化修改字段 entity.setModifiedBy(currentUserId); entity.setModifiedOn(LocalDateTime.now(clock)); } // 实体更新前触发 @PreUpdate public void preUpdate(EntityAuditInfo entity) { Integer currentUserId = currentUserService.getCurrentUserId(); entity.setModifiedBy(currentUserId); entity.setModifiedOn(LocalDateTime.now(clock)); } }
3. 实现当前用户获取服务
创建一个CDI bean,用于获取当前登录用户的ID,这里以Quarkus Security为例(如果使用其他认证方式,可自行调整逻辑):
@ApplicationScoped public class CurrentUserService { @Inject SecurityIdentity securityIdentity; public Integer getCurrentUserId() { // 假设当前用户ID存储在SecurityIdentity的Principal名称中,需根据实际认证逻辑调整 return Integer.valueOf(securityIdentity.getPrincipal().getName()); } }
4. 配置依赖(如果需要)
如果使用Quarkus Security,确保添加对应的依赖到pom.xml(Maven)或build.gradle(Gradle):
<!-- Maven --> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-security</artifactId> </dependency>
注意事项
- 时间类型推荐使用
LocalDateTime而非Date,更符合Java 8+的日期时间API规范,且Quarkus JPA完全支持。 - 实体监听器必须被CDI管理(添加
@ApplicationScoped),才能正常注入CurrentUserService和Clock。 - 如果你的认证方式不是Quarkus Security,比如JWT、Session等,只需修改
CurrentUserService中的逻辑,从对应的上下文获取用户ID即可。
内容的提问来源于stack exchange,提问作者MightyThor
相关产品推荐
相关产品推荐

