You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Quarkus中如何在@ApplicationScoped服务类中注入HttpServerRequest

问题核心原因

  1. @Context是JAX-RS专属的上下文注入注解,仅能在JAX-RS管理的组件(比如@Path标注的资源类、@Provider标注的拦截器/过滤器)中生效,普通CDI Bean(比如自定义的Service)使用@Context注入本身就不被支持,所以会拿到null。
  2. HttpServerRequest是请求级别的对象,和单例作用域的@ApplicationScoped Bean生命周期不匹配,直接注入也会出现作用域不兼容的问题。

可行实现方案

方案1:使用Provider延迟获取(推荐,不改变Service单例特性)

通过CDI提供的Provider包装HttpServerRequest,实现延迟加载,每次调用get()方法时会自动获取当前请求对应的实例,无需修改Service的作用域。
示例代码:

import jakarta.inject.Inject;
import jakarta.inject.Provider;
import io.vertx.core.http.HttpServerRequest;

@Slf4j
@ApplicationScoped
public class TokenService {
    
    // 注意此处用@Inject注入,不要用@Context
    @Inject
    Provider<HttpServerRequest> requestProvider;
    
    public SysUser getUser() {
        HttpServerRequest request = requestProvider.get();
        String authorization = request.getHeader("Authorization");
        log.info(authorization);
        
        // 后续业务逻辑
        return null;
    }
}

如果使用的是旧版Quarkus(基于Java EE),将jakarta.inject替换为javax.inject即可。


方案2:调整Service为请求作用域

将TokenService的作用域从@ApplicationScoped改为@RequestScoped,每个请求对应一个Service实例,此时可以直接注入HttpServerRequest。
示例代码:

import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Inject;
import io.vertx.core.http.HttpServerRequest;

@Slf4j
@RequestScoped
public class TokenService {
    
    // 注意此处用@Inject注入,不要用@Context
    @Inject
    HttpServerRequest request;
    
    public SysUser getUser() {
        String authorization = request.getHeader("Authorization");
        log.info(authorization);
        
        // 后续业务逻辑
        return null;
    }
}

该方案适合业务逻辑较轻的Service,如果Service中存在较重的初始化逻辑,会产生额外的性能开销。


内容的提问来源于stack exchange,提问作者JaveysWuu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 03:21:04