我需要向存储在单个JMS服务器上的不同主题发送/接收消息。
我想使用JmsTemplate
发送和MessageListenerContainer
来注册异步侦听器。
我的配置如下:
<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>
据我所知,singleConnectionFactory
总是返回相同的连接实例,有助于减少创建和关闭的开销
每次jmsTemplate
需要(例如)发送/接收消息时的连接(就像使用普通ConnectionFactory
时那样)。
我的第一个问题是:如果我创建多个jmsTemplate
(s),他们是否可以共享singleConnectionFactory
的引用?或者他们必须分别收到一个不同的实例(singleConnectionFactory1
,singleConnectionFactory2
等)?
阅读SingleConnectionFactory
的API,我发现了这个:
请注意,Spring的消息侦听器容器支持使用共享
Connection
在每个侦听器容器实例中。结合使用SingleConnectionFactory
只对跨多个侦听器容器共享单个JMS连接非常有意义。
这听起来对我来说有点神秘。据我所知,每MessageListenerContainer
只能注册一个监听器,所以我不明白连接的共享程度。
假设我要注册N个监听器:我需要重复N次这样的事情:
<bean
class="org.springframework.jms.listener.SimpleMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destinationName" value="destX" />
<property name="messageListener" ref="listener1outOfN" />
</bean>
在这种情况下,connectionFactory创建了多少个连接?每个ListenerContainer一个或只是一个Connections池?如果我向SimpleMessageListenerContainer
- s提供引用singleConnectionFactory
,该怎么办?
在这种情况下,最好的方法是什么(当然,从表演的角度来看)?
答案 0 :(得分:6)
如果我创建多个jmsTemplate(s),它们是否可以共享一个singleConnectionFactory的引用?
是的,这很好。 SingleConnectionFactory
的javadoc说:
根据JMS Connection模型,这是完全线程安全的(与例如JDBC相反)。
JMS Connection对象是线程安全的,并且可以由多个线程同时使用。因此,不需要使用多个SingleConnectionFactory
bean。
据我所知,每
MessageListenerContainer
只能注册一个监听器,所以我不明白连接的共享程度。
这是真的;但是,每个MessageListenerContainer
可以有多个线程同时处理消息,所有这些线程都使用相同的MessageListener
对象。 MessageListenerContainer
将为所有这些线程使用单个共享Connection
(除非另有配置)。
请注意,Spring的消息侦听器容器支持在每个侦听器容器实例中使用共享Connection。结合使用
SingleConnectionFactory
只对跨多个侦听器容器共享单个JMS连接非常有意义。
换句话说,如果您只拥有一个MessageListenerContainer
,则SingleConnectionFactory
是不必要的,因为单个连接在内部管理到MessageListenerContainer
。如果您有多个侦听器容器,并希望它们全部共享连接,则需要SingleConnectionFactory
。此外,如果您想像在一样共享收听和发送之间的连接,那么SingleConnectionFactory
也是必要的。