1

我需要向/从存储在单个 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),它们都可以共享一个 refsingleConnectionFactory吗?或者他们是否必须每个都接收一个不同的实例(singleConnectionFactory1,,singleConnectionFactory2等)?

阅读 API SingleConnectionFactory,我发现:

请注意,Spring 的消息侦听器容器支持Connection 在每个侦听器容器实例中使用共享。只有在多个侦听器容器之间共享单个 JMS 连接时,组合使用SingleConnectionFactory才真正有意义。

这对我来说听起来有点神秘。据我所知,每个 只能注册 1 个 Listener MessageListenerContainer,所以我不明白连接共享的程度。

假设我想注册 N 个 Listeners:我需要重复 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 一个或只是一个连接池?如果我为SimpleMessageListenerContainer-s 提供一个 refsingleConnectionFactory怎么办?

在这种情况下,最好的方法是什么(当然,从表演的角度来看)?

4

1 回答 1

6

如果我创建多个 jmsTemplate(s),它们是否都可以共享一个指向 singleConnectionFactory 的引用?

是的,这很好。javadocSingleConnectionFactory说:

根据 JMS 连接模型,这是完全线程安全的(与例如 JDBC 相比)。

JMS Connection 对象是线程安全的,可以被多个线程同时使用。所以没有必要使用多个SingleConnectionFactorybean。

据我所知,每个 只能注册 1 个 Listener MessageListenerContainer,所以我不明白连接共享的程度。

这是真实的; 但是,每个线程都MessageListenerContainer可以有多个线程同时处理消息,所有线程都使用同一个MessageListener对象。MessageListenerContainer将为所有这些线程使用一个共享的单一线程Connection(除非配置为其他方式)。

请注意,Spring 的消息侦听器容器支持在每个侦听器容器实例中使用共享连接。只有在多个侦听器容器之间共享单个 JMS 连接时,组合使用SingleConnectionFactory才真正有意义。

换句话说,如果你只有一个MessageListenerContainer,那么SingleConnectionFactory就没有必要了,因为单个连接是在内部管理的MessageListenerContainer。如果您有多个侦听器容器,并希望它们都共享一个连接,那么SingleConnectionFactory是必需的。另外,如果你想在监听和发送之间共享一个连接,就像你做的那样,那么SingleConnectionFactory也是必要的。

于 2012-01-20T14:46:59.880 回答