【问题标题】:NoUniqueBeanDefinitionException in Spring annotation driven configurationSpring注解驱动配置中的NoUniqueBeanDefinitionException
【发布时间】:2017-03-21 03:37:11
【问题描述】:

尝试使用自动装配两个 bean 时出现以下错误

没有定义 [javax.jms.ConnectionFactory] ​​类型的限定 bean: 预期单个匹配 bean,但找到 2:aConnectionFactory、bConnectionFactory

Description:

Parameter 1 of method jmsListenerContainerFactory in org.springframework.boot.autoconfigure.jms.JmsAnnotationDrivenConfiguration required a single bean, but 2 were found:
        - aConnectionFactory: defined by method 'aConnectionFactory' in package.Application
        - bConnectionFactory: defined by method 'bConnectionFactory' in package.Application


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

我有这个注解驱动的配置:

@SpringBootApplication
@EnableIntegration
@IntegrationComponentScan
public class Application  extends SpringBootServletInitializer implements
 WebApplicationInitializer {

    @Resource(name = "aConnectionFactory")
    private ConnectionFactory aConnectionFactory;

    @Resource(name = "bConnectionFactory")
    private ConnectionFactory bConnectionFactory;

    @Bean
    public IntegrationFlow jmsInboundFlow() {
        return IntegrationFlows
                    .from(
                        Jms.inboundAdapter(aConnectionFactory)
                                            .destination(aQueue),
                        e -> e.poller( Pollers.fixedRate(100, 
TimeUnit.MILLISECONDS).maxMessagesPerPoll(100))
                     ).channel("entrypoint")
                     .get();
}

   @Bean
    public IntegrationFlow jmsInboundFlowB() {
        return IntegrationFlows
                    .from(
                        Jms.inboundAdapter(bConnectionFactory)
                                            .destination(bQueue),
                        e -> e.poller( Pollers.fixedRate(100, 
TimeUnit.MILLISECONDS).maxMessagesPerPoll(100))
                     ).channel("entrypoint")
                     .get();
}


    @Bean(name = "aConnectionFactory")
    @Profile({"weblogic"})
    public ConnectionFactory aConnectionFactory() {
        ConnectionFactory factory = null;
        JndiTemplate jndi = new JndiTemplate();
        try {
          factory = (ConnectionFactory) jndi.lookup("jms/ConnectionFactory");
        } catch (NamingException e) {
            logger.error("NamingException for jms/ConnectionFactory", e);
        }

        return factory;
    }

    @Bean(name = "bConnectionFactory")
    @Profile({"weblogic"})
    public ConnectionFactory bConnectionFactory() {
        ConnectionFactory factory = null;
        JndiTemplate jndi = new JndiTemplate();
        try {
          factory = (ConnectionFactory) jndi.lookup("jms/ConnectionFactory");
        } catch (NamingException e) {
            logger.error("NamingException for jms/ConnectionFactory", e);
        }

        return factory;
    }

}

你知道这段代码有什么问题吗?这似乎是直截了当的,但指定限定符不起作用,我也尝试使用@Resource。我错过了什么?

任何帮助表示赞赏。

【问题讨论】:

  • spring 混淆了 @Resource(name = "aConnectionFactory") 和 @Bean(name = "aConnectionFactory")。正如控制台建议的那样,您需要将其中一个标记为主要(与 bConnectionFactory 相同)

标签: spring spring-integration spring-annotations


【解决方案1】:

问题在于

javax.jms.ConnectionFactory 是单例的,你需要一个类型的对象!

您的问题的解决方案:

  • 如果您需要两个创建对象并扩展 ConnectionFactory 的对象 他们根据需要更改范围。
  • 试试@Scope("singleton") 或@Scope("prototype")。
  • 如果收到错误,请创建一个对象。然后使用范围 @Scope("singleton")
  • “其他两个”毁坏已经在使用和设置此类的另一个类。

【讨论】:

  • 不确定你的建议是什么——我需要两个相同类型的单例,据我所知,我可以有两个相同的单例 bean。我正在寻找的是自动装配正确的。
  • 那是正确的,找到实现接口或类,在你的项目中的某个地方,看到错误是干净的。尝试为你的两只小熊定义 @Scope("prototype") 的范围
  • 这并没有解决问题 - 问题不在于这里的范围 - 代码没有任何问题。请查看已接受的答案及其下方的 cmets,它们为问题提供了正确的解决方案。
【解决方案2】:

您的代码没有问题。

这只是来自 Spring Boot 的 JmsAnnotationDrivenConfiguration,它不喜欢你的两个 ConnectionFactory bean,但只需要一个。

  1. 为什么不遵循该报告建议并用@Primary 标记其中之一?

  2. 看起来您没有使用 Spring Boot JMS 自动配置功能,因此禁用 JmsAnnotationDrivenConfiguration: http://docs.spring.io/spring-boot/docs/1.4.1.RELEASE/reference/htmlsingle/#using-boot-disabling-specific-auto-configuration

【讨论】:

  • 感谢 Artem,我不能将它们中的任何一个标记为 @Primary,因为我需要其中两个自动装配以定义两个不同的 jmsInboudFlows(来自使用不同连接工厂的不同队列)。
  • 没错,但您可以将@Autowired@Qualifier 一起使用。但无论如何,我想,最好禁用JmsAnnotationDrivenConfiguration,因为你完全不使用它的功能。
  • 请注意,为了在最新版本的 Spring Boot 中禁用它,您需要排除 JmsAutoConfiguration 因为 JmsAnnotationDrivenConfiguration 不是公共的。
猜你喜欢
  • 2017-01-18
  • 2011-05-25
  • 2013-04-08
  • 2012-09-20
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
  • 1970-01-01
相关资源
最近更新 更多