Spring Jms中的生产者和消费者使用相同的连接工厂?

时间:2014-11-13 10:52:17

标签: java spring-jms

我有一个组件从队列中读取消息,同时将处理过的消息发送到另一个队列。因此,该组件既是消息使用者又是生产者。为了配置它们,我需要一个用于消费的连接工厂和另一个用于生产的连接工厂。这是弹簧配置的一部分。

<!-- Configuration for listener -->
<bean id="mdc.TargetConnectionFactory4Listener" class="com.tibco.tibjms.TibjmsConnectionFactory">  
    <property name="serverUrl" value="tcp://localhost:7222"/>
</bean>

<bean id="mdc.ConnectionFactory4Listener" class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">  
    <property name="targetConnectionFactory" ref="mdc.TargetConnectionFactory"/>
    <property name="username" value="admin" />
    <property name="password" value="test" />
</bean>

<bean id="mdc.InputQueue" class="com.tibco.tibjms.TibjmsQueue">  
    <constructor-arg>  
        <value>INPUT_QUEUE</value>  
    </constructor-arg>  
</bean>

<bean id="mdc.JmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">  
    <property name="connectionFactory" ref="mdc.ConnectionFactory4Listener" />  
    <property name="destination" ref="mdc.InputQueue" />  
    <property name="messageListener" ref="mdc.MessageReceiver" />  
    ......
</bean>

<!-- Configuration for sender -->
<bean id="mdc.TargetConnectionFactory4Sender" class="com.tibco.tibjms.TibjmsQueue">  
    <property name="serverUrl" value="tcp://localhost:7222"/>
</bean>

<bean id="mdc.CachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
    <property name="targetConnectionFactory" ref="mdc.TargetConnectionFactory4Sender" />
    <property name="sessionCacheSize" value="50" />
</bean>

<bean id="mdc.OutputQueue" class="com.tibco.tibjms.TibjmsQueue">  
    <constructor-arg>  
        <value>DISCOVERY_QUEUE</value>  
    </constructor-arg>  
</bean>

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

<bean id="mdc.MessageReceiver" class="net.siemens.discovery.queue.QueueMessageListener">
    <property name="jmsTemplate" ref="mdc.JmsTemplate" />  
    <property name="destination" ref="mdc.OutputQueue" />
    ......
</bean>

这两个队列在同一个EMS服务器上运行。有些人对此配置有意见:可以只使用一个ConnectionFactory配置它们,并且不需要两个实例。但是,如果我使用一个ConnectionFactory实例,则在DefaultMessageListenerContainer和CachingConnectionFactory中使用该实例(在JmsTemplate中进一步使用)。我不知道他们是否互相影响。

1 个答案:

答案 0 :(得分:1)

使用单一连接工厂是完全正常的;在这种情况下使用2个工厂是非常不寻常的。

实际上,如果您想对容器线程执行JmsTemplate操作,并且希望交互在事务中运行(容器中为sessionTransacted = true),那么您必须使用相同的连接工厂。如果存在异常,这允许所有内容回滚。

在侦听器容器中使用缓存连接工厂时,应将连接工厂cacheConsumers设置为false。 (见this answer for more information