Spring JMS Connections: performance considerations
-
06-11-2019 - |
Question
I have the need to send/receive messages towards/from different topics stored on a single JMS Server.
I would like to use JmsTemplate
for sending and MessageListenerContainer
for registering asyncronous listeners.
My configuration looks like this:
<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">xxx</prop>
<prop key="java.naming.provider.url">yyy</prop>
</props>
</property>
</bean>
<bean id="connectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate" ref ="jndiTemplate"/>
<property name="jndiName" value="TopicConnectionFactory"/>
</bean>
<bean id="singleConnectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
<constructor-arg ref="connectionFactory"/>
</bean>
<bean id="tosJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="singleConnectionFactory"/>
<property name="destinationResolver" ref="destinationResolver"/>
<property name="pubSubDomain" value="true"/>
</bean>
As far as I understood, the singleConnectionFactory
, returning always the same connection instance, helps reducing the overhead of creating and closing
a connection each time a jmsTemplate
needs (for example) to send/receive a message (as it would be when using a normal ConnectionFactory
).
My first question is: if I create multiple jmsTemplate
(s), can they all share a ref to a singleConnectionFactory
? Or do they have to receive a distinct instance each (singleConnectionFactory1
, singleConnectionFactory2
, etc)?
Reading the API for SingleConnectionFactory
, I found this:
Note that Spring's message listener containers support the use of a shared
Connection
within each listener container instance. UsingSingleConnectionFactory
in combination only really makes sense for sharing a single JMS Connection across multiple listener containers.
This sound a bit cryptic to me. As far as I know, it is possible to register only 1 Listener per MessageListenerContainer
, so I don't understand to what extent is a connection shared.
Suppose I want to register N Listeners: I will need to repeat N times something like this:
<bean
class="org.springframework.jms.listener.SimpleMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destinationName" value="destX" />
<property name="messageListener" ref="listener1outOfN" />
</bean>
How many Connections are created in such case from connectionFactory? One for each ListenerContainer or just a pool of Connections? And what if I provide the SimpleMessageListenerContainer
-s with a ref to singleConnectionFactory
?
What is the best approach (from the point of view of the performances, of course) in this case?
No correct solution