如何确保Quarkus中@ServerRequestFilter先于@Produces方法执行?
问题分析
你遇到的核心问题是:@ServerRequestFilter 方法和 @Produces 方法分属不同执行阶段,@Priority 注解仅能管控同类型组件的执行顺序(比如多个过滤器之间),跨阶段的执行顺序无法通过它约束。
具体来说,@Produces 方法会在依赖注入阶段被触发(当其他Bean需要注入 JsonWebToken 时),而 @ServerRequestFilter 是在请求处理链阶段执行。如果某个依赖 JsonWebToken 的Bean在过滤器执行前就完成了实例化和注入,生产者方法会先被调用,导致返回的 jwt 为null。
解决方案
这里提供两种可靠的解决思路:
方案一:拆分职责,用RequestScoped Holder类桥接
把JWT的存储、解析、生产拆分为不同Bean,确保过滤器在请求早期执行,生产者从Holder中获取已解析的JWT。
- 定义RequestScoped的JWT持有类:
@RequestScoped public class JwtHolder { private JsonWebToken jwt; public void setJwt(JsonWebToken jwt) { this.jwt = jwt; } public JsonWebToken getJwt() { return jwt; } }
- 修改过滤器类,专注解析并设置JWT到Holder:
@RequestScoped public class JwtFilter { @Inject JWTParser jwtParser; @Inject JwtHolder jwtHolder; // 设置认证级别的优先级,确保在大部分业务逻辑前执行 @ServerRequestFilter(priority = Priorities.AUTHENTICATION) public void parseAuthorizationHeader(ContainerRequestContext context) { String authHeader = context.getHeaderString("Authorization"); JsonWebToken jwt = jwtParser.parse(authHeader); jwtHolder.setJwt(jwt); } }
- 单独编写生产者类,从Holder中获取JWT:
@RequestScoped public class JwtProducer { @Inject JwtHolder jwtHolder; @Produces public JsonWebToken getJwt() { return jwtHolder.getJwt(); } }
方案二:移除过滤器,在生产者中懒加载解析
如果不需要过滤器执行额外逻辑(比如权限校验),可以直接在生产者方法中实现懒加载解析,确保获取JWT时一定完成了解析:
@RequestScoped public class ApplicationJwtFactory { @Inject JWTParser jwtParser; @Inject ContainerRequestContext context; private JsonWebToken jwt; @Produces public JsonWebToken getJwt() { if (jwt == null) { String authHeader = context.getHeaderString("Authorization"); jwt = jwtParser.parse(authHeader); } return jwt; } }
这种方式不需要依赖过滤器,每次获取JWT时都会先检查是否已解析,彻底避免了顺序问题。
内容的提问来源于stack exchange,提问作者Mambazo
相关产品推荐
相关产品推荐

