0
votes

I have a component which reads messages from a queue and meanwhile sends the processed messages to another queue. Therefore, this component is both a message consumer and producer. For configuring them, I need a connection factory for consuming and another connection factory for the producing. Here is part of the spring configuration.

<!-- 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>

The two queues are running on the same EMS server. Some has opinions about this configurations: they can be configured by using only one ConnectionFactory and two instances are not necessary. However, if I use one ConnectionFactory instance, then the instance is used both in the DefaultMessageListenerContainer and the CachingConnectionFactory (further used in JmsTemplate). I don't know whether they have impact on each other.

1

1 Answers

1
votes

It is perfectly normal to use a single connection factory; it is very unusual to use 2 factories in this case.

In fact, if you want to perform JmsTemplate operations on the container thread and you want the interactions to run in a transaction (sessionTransacted = true in the container), then you must use the same connection factory. This allows everything to roll back if there's an exception.

When using a caching connection factory in the listener container you should set the connection factory cacheConsumers to false. (See this answer for more information.