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

Spring Boot多类调用时@Component单例与自定义单例的选型问题

核心结论

Spring 全局仅会创建一个 RepositoryComponent 实例供A、B、C三者共用,不需要自行实现单例类。
Spring 中所有未显式指定 @Scope 注解的 @Component 类默认都是 singleton 作用域,容器初始化时会创建唯一的实例,后续所有@Autowired注入该类的地方,拿到的都是同一个对象,内部的Map存储自然也是全局共用的,完全匹配你的需求。

注意事项
  • 你当前代码中使用的 HashMap 是非线程安全类,如果存在多线程并发读写更新Map的场景,会出现数据错乱问题,建议替换为线程安全的 ConcurrentHashMap。
  • 只有你主动给 RepositoryComponent 加上 @Scope("prototype") 注解时,才会每次注入都创建独立实例,默认配置不会出现这个情况。
  • 自行实现的非Spring托管单例类无法直接注入其他Spring Bean,后续扩展能力受限,优先使用Spring托管的单例Bean更符合Spring项目开发规范。
优化后参考代码
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.concurrent.ConcurrentHashMap;

// 不推荐自行实现的非Spring托管单例
class Repository {
    private static final Repository INSTANCE = new Repository();
    private final ConcurrentHashMap<String, Config> db = new ConcurrentHashMap<>();

    private Repository() {}

    public static Repository getInstance() {
        return INSTANCE;
    }

    public String getConfig(String key) {
        Config config = db.get(key);
        return config != null ? config.toString() : null;
    }

    // 补充写数据方法,保证线程安全
    public void updateConfig(String key, Config config) {
        db.put(key, config);
    }
}

// 推荐用法:Spring托管单例
@Component
class RepositoryComponent {
    private final ConcurrentHashMap<String, Config> db = new ConcurrentHashMap<>();

    public String getConfig(String key) {
        Config config = db.get(key);
        return config != null ? config.toString() : null;
    }

    public void updateConfig(String key, Config config) {
        db.put(key, config);
    }
}

@Component
class A {
    @Autowired
    private RepositoryComponent c;

    public void someMethod() {
        // 两种方式拿的都是全局唯一的存储实例
        Repository.getInstance().getConfig("key");
        c.getConfig("key");
    }
}

@Component
class B {
    @Autowired
    private RepositoryComponent c;

    public void someMethod() {
        Repository.getInstance().getConfig("key");
        c.getConfig("key");
    }
}

@Component
class C {
    @Autowired
    private RepositoryComponent c;

    public void someMethod() {
        Repository.getInstance().getConfig("key");
        c.getConfig("key");
    }
}

// 补充Config类示例,可根据实际业务调整
class Config {
    // 业务字段
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 09:30:00