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

如何通过Spring配置多次实例化带不同依赖的服务?

解决方案:Spring中实现多实例领域服务(带不同依赖)

方案一:使用@Qualifier区分同类型Bean

通过给不同环境的Bean添加唯一标识,明确绑定领域服务的依赖,同时让应用层能精准注入对应实例。

修改配置类

OfflineConfig

@Configuration
class OfflineConfig {

    @Bean
    @Qualifier("offlineEventBus")
    fun offlineEventBus(): EventBus {
        return InMemoryEventBus()
    }

    @Bean
    @Qualifier("offlineCommandBus")
    fun offlineCommandBus(): CommandBus {
        return InMemoryCommandBus()
    }

    @Bean
    @Qualifier("offlineDoSomethingHandler")
    fun offlineDoSomethingCommandHandler(
        @Qualifier("offlineEventBus") eventBus: EventBus,
        @Qualifier("offlineCommandBus") commandBus: CommandBus,
        useCase: UseCase<DoSomething>,
        someRepo: SomeRepository
    ): CommandHandler<DoSomething> {
        return CommandHandler(eventBus, commandBus, useCase, DoSomething::class.java, someRepo)
    }

    @Bean
    @Qualifier("offlineDoSomethingElseHandler")
    fun offlineDoSomethingElseCommandHandler(
        @Qualifier("offlineEventBus") eventBus: EventBus,
        @Qualifier("offlineCommandBus") commandBus: CommandBus,
        useCase: UseCase<DoSomethingElse>,
        someRepo: SomeRepository
    ): CommandHandler<DoSomethingElse> {
        return CommandHandler(eventBus, commandBus, useCase, DoSomethingElse::class.java, someRepo)
    }
}

OnlineConfig

@Configuration
class OnlineConfig {

    @Bean
    @Qualifier("onlineEventBus")
    fun onlineEventBus(): EventBus {
        return OnlineEventBus()
    }

    @Bean
    @Qualifier("onlineCommandBus")
    fun onlineCommandBus(): CommandBus {
        return OnlineCommandBus()
    }

    @Bean
    @Qualifier("onlineDoSomethingHandler")
    fun onlineDoSomethingCommandHandler(
        @Qualifier("onlineEventBus") eventBus: EventBus,
        @Qualifier("onlineCommandBus") commandBus: CommandBus,
        useCase: UseCase<DoSomething>,
        someRepo: SomeRepository
    ): CommandHandler<DoSomething> {
        return CommandHandler(eventBus, commandBus, useCase, DoSomething::class.java, someRepo)
    }

    @Bean
    @Qualifier("onlineDoSomethingElseHandler")
    fun onlineDoSomethingElseCommandHandler(
        @Qualifier("onlineEventBus") eventBus: EventBus,
        @Qualifier("onlineCommandBus") commandBus: CommandBus,
        useCase: UseCase<DoSomethingElse>,
        someRepo: SomeRepository
    ): CommandHandler<DoSomethingElse> {
        return CommandHandler(eventBus, commandBus, useCase, DoSomethingElse::class.java, someRepo)
    }
}

应用层注入使用

@Component
class AppService {
    @Autowired
    @Qualifier("offlineDoSomethingHandler")
    private lateinit var offlineHandler: CommandHandler<DoSomething>

    @Autowired
    @Qualifier("onlineDoSomethingHandler")
    private lateinit var onlineHandler: CommandHandler<DoSomething>

    // 业务方法中按需使用对应Handler
    fun handleOfflineTask() {
        offlineHandler.execute(DoSomething())
    }

    fun handleOnlineTask() {
        onlineHandler.execute(DoSomething())
    }
}

方案二:创建独立Spring子上下文隔离配置

如果两套服务需要完全隔离(避免任何Bean冲突),可以创建多个独立的ApplicationContext,分别加载对应配置,还可通过父上下文共享公共Bean(如Repository、UseCase)。

实现代码

// 父上下文加载公共依赖(如Repository、UseCase)
val parentContext = AnnotationConfigApplicationContext(CommonConfig::class.java)

// 加载Offline环境上下文
val offlineContext = AnnotationConfigApplicationContext().apply {
    parent = parentContext
    register(OfflineConfig::class.java, MyDomainConfig::class.java)
    refresh()
}
val offlineDoSomethingHandler = offlineContext.getBean(CommandHandler<DoSomething>::class.java)

// 加载Online环境上下文
val onlineContext = AnnotationConfigApplicationContext().apply {
    parent = parentContext
    register(OnlineConfig::class.java, MyDomainConfig::class.java)
    refresh()
}
val onlineDoSomethingHandler = onlineContext.getBean(CommandHandler<DoSomething>::class.java)

方案选择建议

  • 方案一:适合大部分场景,配置简单,Bean共享性高,仅通过标识区分不同实例。
  • 方案二:适合两套服务依赖完全独立、冲突较多的场景,完全隔离上下文,避免任何Bean命名或依赖冲突,但需手动管理上下文生命周期。

内容的提问来源于stack exchange,提问作者Grégory Elhaimer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 04:37:06