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

标注@Singleton与@Provides的方法被多次调用问题排查

问题根源及修复方案

核心错误点

  • 构造函数判断逻辑完全写反
    你Library类构造函数里的if (Objects.nonNull(injector))逻辑搞反了:当前代码是injector已经存在时,反而重新创建新的Injector实例,而原本应该是injector为空时才初始化。而且每次调用initializeLib都会new一个Library对象,不管injector有没有初始化,都会执行构造函数里的log.info("Bean getting created"),这就是日志重复打印的直接原因。

  • 缺乏线程安全保障
    没有做线程同步处理,多线程场景下可能会多次创建injector,导致更多重复实例。

  • Spring的@Singleton约束未生效
    虽然你给getSomeExposedComponent加了@Singleton,但initializeLib每次调用都可能生成新的组件实例(因为injector被重复创建),导致Spring的单例约束失效。

修复后的Library代码

public final class Library {

    private static volatile Injector injector;
    // 加volatile保证多线程下的实例可见性

    private Library() {
        // 私有构造,避免外部随意实例化
    }

    public static SomeExposedComponent initializeLib(SomeClass someclass) {
        if (Objects.isNull(injector)) {
            // 双重检查锁实现线程安全的单例初始化
            synchronized (Library.class) {
                if (Objects.isNull(injector)) {
                    log.info("Bean getting created");
                    // 若需要将someclass传入Module,需修改LibraryModule构造接收该参数
                    injector = createInjector(new LibraryModule(someclass));
                }
            }
        }
        return injector.getInstance(SomeExposedComponent.class);
    }
}

额外说明

原代码里的SomeClass someclass参数在构造函数中未被使用,你需要确认是否要将该参数传递给LibraryModule,如果是,要修改LibraryModule的构造方法接收该参数,在创建injector时传入。

修正后,只有第一次调用initializeLib时才会打印日志并创建injector,后续调用直接复用已有的injector获取组件实例,配合Spring的@Singleton,就能保证SomeExposedComponent是单例。

内容的提问来源于stack exchange,提问作者siddhartha kumar verma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 15:55:22