Spring Qualifiers问题两个类型为“org.springframework.jms.core.JmsTemplate”的bean

时间:2014-02-28 17:31:46

标签: java spring

我一定很遗憾。这是我的Spring配置XML的片段:

<bean id="queueDestination" class="com.ibm.mq.jms.MQQueue">
    <constructor-arg value="TestQ" />
</bean>

<bean id="topicDestination" class="com.ibm.mq.jms.MQTopic">
    <constructor-arg value="TestTopic" />
</bean>

<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="jmsQueueConnectionFactory" />
        <property name="defaultDestination" ref="queueDestination" />
</bean>

<bean id="jmsTopicTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="jmsTopicConnectionFactory" />
        <property name="defaultDestination" ref="topicDestination" />
</bean>

以下是尝试将其自动装入的代码:

@Autowired
@Qualifier("jmsQueueTemplate")
private JmsTemplate jmsQueueTemplate;

@Autowired
@Qualifier("queueDestination")
private Destination queueDestination;

我一直在:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'publish': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.springframework.jms.core.JmsTemplate com.vulab.publishsubscribe.Publish.jmsTemplate; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [org.springframework.jms.core.JmsTemplate] is defined: expected single matching bean but found 2: [jmsQueueTemplate, jmsTopicTemplate]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1120)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:607)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)

请帮助我理解我所缺少的内容。

我觉得这与@Autowire或@Qualifier无关。我认为这是因为我有两个用“org.springframework.jms.core.JmsTemplate”类定义的bean。

感谢。

2 个答案:

答案 0 :(得分:1)

我将您的代码与this tutorial进行了比较。我认为您的bean中不需要<qualifier/>属性。相反,您可以使用bean ID作为@Qualifier注释中的值。

此外,请确保在applicationContext.xml的顶部注册AutowiredAnnotationBeanPostProcessor。

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

Here's another tutorial,如果向下滚动,您会找到@Qualifier的示例。

答案 1 :(得分:1)

我遇到了同样的问题,而我仍然在学习Spring JMS,我发现了

<bean id="..." class="org.springframework.jms.core.JmsTemplate"> : 
</bean>

应该定义一次,与ConnectionFactory相同,至少在相同的上下文中。

我的解决方案是在没有 defaultDestination 的情况下定义一个JmsTemplate

(使用后期样本)

<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="jmsQueueConnectionFactory" />
</bean>

然后只需要一个POJO来发送消息:

import javax.jms.Destination;
public class MySender {
    private final JmsTemplate template;
    private Destination queue;

    public ShortcodeRelaySender(JmsTemplate template, Destination queue) {
        this.template = template;
        this.queue = queue;
    }

    public void send(String msg) {
        template.convertAndSend(queue, msg);
    }
}

然后定义两个bean,每个队列目标一个:

<bean id="queueSender" class="my.package.MySender">
    <constructor-arg index="0" ref="jmsQueueTemplate"/>
    <constructor-arg index="1" ref="queueDestination"/>
</bean>

<bean id="topicSender" class="my.package.MySender">
    <constructor-arg index="0" ref="jmsQueueTemplate"/>
    <constructor-arg index="1" ref="topicDestination"/>
</bean>

我不知道这是否是解决问题的最佳方法,但我可以在同一个环境中发送多个目的地。

也许可以帮助别人:)

BR。