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

Spring手动调用prototype Bean方法报参数对应类型Bean不存在问题问询

问题认知纠正

你的认知确实存在错误。Spring对所有标注@Bean的工厂方法,无论作用域是singleton还是prototype,默认都会尝试从Spring上下文中查找匹配的Bean来注入方法入参,不会因为是prototype就跳过参数依赖检查。
你在connectionFactoryManager中直接调用connectionFactory(serviceProps)属于配置类内部的普通方法调用,Spring不会干预这个调用的传参,但Spring本身会扫描到@Bean标注的connectionFactory方法,尝试校验这个Bean的依赖是否满足,因此会抛出找不到JmsServiceProps类型Bean的错误。

解决方案

你需要将批量创建的ConnectionFactory都纳入Spring上下文管理,这里提供两种可行方案:

方案1:通过ApplicationContext动态获取prototype Bean

保留connectionFactory的prototype Bean定义,调用getBean时手动传入参数,适合后续还需要动态创建不同参数的ConnectionFactory的场景:

@Configuration
class JmsConfiguration(
    val props: JmsProperties,
    val applicationContext: ApplicationContext
) : JmsListenerConfigurer {
    @Bean
    fun connectionFactoryManager(): ConnectionFactoryManager {
        val connectionFactories = props.services.map { serviceProps ->
            // 动态传入serviceProps参数获取prototype实例
            applicationContext.getBean("connectionFactory", serviceProps) as ConnectionFactory
        }.toList()
        return ConnectionFactoryManager(connectionFactories)
    }

    @Bean
    @Scope(BeanDefinition.SCOPE_PROTOTYPE)
    fun connectionFactory(@Autowired(required = false) serviceProps: JmsServiceProps): ConnectionFactory {
        val cf = MQConnectionFactory()
        // 基于serviceProps完成配置逻辑
        return cf
    }

    override fun configureJmsListeners(registrar: JmsListenerEnpointRegistrar) {
        // 原有自定义监听器注册逻辑
    } 
}

注意给方法参数加@Autowired(required = false),关闭Spring启动时的依赖校验,避免启动报错。

方案2:手动注册Bean到Spring上下文

去掉connectionFactory的@Bean注解,创建实例后手动注册到容器,更适合当前固定基于配置批量创建实例的场景:

@Configuration
class JmsConfiguration(
    val props: JmsProperties,
    val beanFactory: ConfigurableListableBeanFactory
) : JmsListenerConfigurer {
    @Bean
    fun connectionFactoryManager(): ConnectionFactoryManager {
        val connectionFactories = props.services.mapIndexed { index, serviceProps ->
            val cf = createConnectionFactory(serviceProps)
            // 自定义Bean名称注册到上下文,方便后续其他组件按名称注入
            beanFactory.registerSingleton("connectionFactory-$index", cf)
            cf
        }.toList()
        return ConnectionFactoryManager(connectionFactories)
    }

    // 作为普通工具方法,不需要@Bean注解
    private fun createConnectionFactory(serviceProps: JmsServiceProps): ConnectionFactory {
        val cf = MQConnectionFactory()
        // 基于serviceProps完成配置逻辑
        return cf
    }

    override fun configureJmsListeners(registrar: JmsListenerEnpointRegistrar) {
        // 原有自定义监听器注册逻辑
    } 
}

后续其他组件可以通过@Qualifier("connectionFactory-{索引}")注入指定实例,或者通过List<ConnectionFactory>注入所有实例。

内容的提问来源于stack exchange,提问作者mr.nothing

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 10:51:03