Quarkus中EntityListener不支持注入时访问CurrentUserBean的方案问询
解决方案
Quarkus中EntityListener不属于CDI托管Bean,因此@Inject注解不会生效,你可以通过以下两种方案实现需求:
方案1:程序式获取CDI托管的CurrentUserBean
直接通过CDI提供的静态API手动获取CurrentUserBean实例,无需依赖注入注解:
import javax.enterprise.inject.spi.CDI; public class EntityListener { @PrePersist void onPersist(Object entity) { CurrentUserBean currentUserBean = getCurrentUser(); // [...] entity.setCreatedBy(currentUserBean.userId); } @PreUpdate void onUpdate(Object entity) { CurrentUserBean currentUserBean = getCurrentUser(); // [...] entity.setUpdatedBy(currentUserBean.userId); } private CurrentUserBean getCurrentUser() { return CDI.current().select(CurrentUserBean.class).get(); } }
方案2:直接读取JWT令牌的用户ID
由于你使用的是JWT无状态服务,也可以跳过CurrentUserBean,直接获取当前请求的JWT实例读取用户ID:
import javax.enterprise.inject.spi.CDI; import org.eclipse.microprofile.jwt.JsonWebToken; public class EntityListener { @PrePersist void onPersist(Object entity) { Long userId = getUserIdFromJwt(); // [...] entity.setCreatedBy(userId); } @PreUpdate void onUpdate(Object entity) { Long userId = getUserIdFromJwt(); // [...] entity.setUpdatedBy(userId); } private Long getUserIdFromJwt() { JsonWebToken jwt = CDI.current().select(JsonWebToken.class).get(); // 替换为你JWT中userId对应的Claim名称 return jwt.getClaim("userId"); } }
注意事项
- 两种方案都需要保证JPA持久化操作执行时处于活跃的请求上下文内,异步线程、应用启动阶段执行的JPA操作会因无请求上下文抛出异常,这类场景建议在调用持久化方法时手动传入用户ID。
- 请求作用域的Bean通过CDI API获取时,会自动返回当前请求对应的独立实例,不存在线程安全问题。
内容的提问来源于stack exchange,提问作者Tim
相关产品推荐
相关产品推荐

