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

Request-scoped Bean在@RestController可用,HttpFilter中抛ScopeNotActiveException

Request-Scope Bean在自定义HttpFilter中抛出ScopeNotActiveException的原因及解决方法

问题根源

你的自定义JwtPreAuthorizationConfigurer是单例Bean,而TenantContext是请求作用域的Bean。虽然请求已经到达处理线程,但Spring的请求上下文(RequestContextHolder)此时还没绑定到当前线程——原因是你的Filter执行顺序在Spring的RequestContextFilter之前,或者项目中未配置RequestContextFilter/RequestContextListener。

而@RestController中的方法能正常工作,是因为Controller的方法是被DispatcherServlet调用的:DispatcherServlet会在处理请求前先初始化请求上下文并绑定到RequestContextHolder,此时请求作用域的Bean可以正常获取实例。

解决方案

方案1:配置RequestContextFilter并调整Filter执行顺序

首先注册RequestContextFilter,它负责将请求上下文绑定到线程:

@Configuration
class PreAuthorizationHttpHeaderFilterConfig {

    @Bean
    public RequestContextFilter requestContextFilter() {
        return new RequestContextFilter();
    }

    @Bean
    @Order(9991) // 确保在RequestContextFilter之后执行(默认order为9990)
    JwtPreAuthorizationConfigurer jwtPreAuthorizationConfigurer() {
        return new JwtPreAuthorizationConfigurer();
    }

    @Bean
    @RequestScope
    TenantContext tenantContext() {
        return new TenantContext();
    }
}

注:RequestContextFilter的默认执行顺序是Ordered.REQUEST_WRAPPER_FILTER_MAX_ORDER - 10(即9990),所以给自定义Filter设置更大的order值,让它后执行。

方案2:用ObjectFactory延迟获取请求作用域Bean

在Filter中注入ObjectFactory<TenantContext>,延迟到doFilter方法中获取Bean实例——此时请求上下文已经绑定:

public class JwtPreAuthorizationConfigurer extends HttpFilter {

    @Resource
    private ObjectFactory<TenantContext> tenantContextFactory;

    @Override
    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        TenantContext tenantContext = tenantContextFactory.getObject();
        tenantContext.getIssuerUri(); // 正常调用
        chain.doFilter(request, response);
    }
}

方案3:显式配置请求作用域Bean的代理模式(可选)

确保TenantContext的Bean生成CGLIB代理(异常中已显示有代理,但显式配置更稳妥):

@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
TenantContext tenantContext() {
    return new TenantContext();
}

该方案需配合方案1或2使用,核心还是要保证请求上下文已初始化。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 12:08:13