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

自定义Spring @Scope实现多租户Bean隔离时实例不切换问题咨询

问题原因及解决方案

1. 自定义Scope未向Spring容器注册

你仅实现了TenantScope类,Spring默认无法识别tenant这个自定义作用域,需要主动完成注册:

@Configuration
public class ScopeConfig {
    @Bean
    public CustomScopeConfigurer tenantScopeConfigurer() {
        CustomScopeConfigurer configurer = new CustomScopeConfigurer();
        configurer.addScope("tenant", new TenantScope());
        return configurer;
    }
}

2. @Scope未设置正确的代理模式

@Scope默认的代理模式是ScopedProxyMode.DEFAULT(等同于无代理),如果你的some_API Bean被注入到单例Bean中,Spring启动时只会初始化一次实例,后续调用永远返回该对象。需要指定代理模式让Spring每次调用都从当前Scope中获取真实实例:

@Scope(scopeName = "tenant", proxyMode = ScopedProxyMode.TARGET_CLASS)
@Bean 
public SomeAPI someAPI() {
     /* Load tenant credentials.. */
     return new SomeAPI(credentials);
}

注:如果SomeAPI是接口实现类,也可以用ScopedProxyMode.INTERFACES减少代理开销。

3. TenantScope的get()方法实现错误

你注释省略了get()方法的实现,若逻辑错误也会导致始终返回同一个对象,正确实现参考:

@Override
public Object get(String name, ObjectFactory<?> objectFactory) {
    String tenantId = getConversationId();
    if (tenantId == null) {
        throw new IllegalStateException("当前无租户上下文");
    }
    String scopeKey = tenantId + ":" + name;
    scopedObjects.computeIfAbsent(scopeKey, k -> objectFactory.getObject());
    return scopedObjects.get(scopeKey);
}

注意:存储key需要同时拼接租户ID和Bean名称,避免同租户下不同Bean的实例冲突。

4. 测试代码注入方式错误

如果你的测试代码中是直接@Autowired注入的some_API实例,没有设置代理模式的前提下,注入的就是首次初始化的固定实例,不会随租户上下文切换而变化,配置代理模式后即可解决。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 15:57:02