8

这里与 Spring CachingConnectionFactory 相关的 java 文档有评论:

注意:此 ConnectionFactory 需要显式关闭从其共享连接中获得的所有会话。无论如何,这是本机 JMS 访问代码的通常建议。但是,对于这个 ConnectionFactory,它的使用是强制性的,以便实际允许 Session 重用。

我不清楚如何在我的应用程序中使用以下给定的配置来处理这个问题。

<bean id="springApp" class="com.codereq.springcore.jms.SpringJMSListenerApp"  />

<bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="jmsConnectionFactory"/>
    <property name="destination" ref="destination"/>
    <property name="messageListener" ref="messageListener"/>
    <property name="sessionTransacted" value="true"/>
    <property name="concurrentConsumers" value="5" />
    <property name="maxConcurrentConsumers" value="15" />
</bean>

<bean id="messageListener" class="com.codereq.springcore.jms.MessageListenerApp" />

<bean id="jmsConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory"
        p:targetConnectionFactory-ref="emsConnectionFactory"
        p:sessionCacheSize="100" 
        p:cacheConsumers="true" />

<bean id="emsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="GenericConnectionFactory"/>
    <property name="jndiTemplate" ref="jndiTemplate"/>
</bean>


<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
        <props>
            <prop key="java.naming.factory.initial">com.tibco.tibjms.naming.TibjmsInitialContextFactory</prop>
            <prop key="java.naming.provider.url">tibjmsnaming://localhost:7222</prop>
            <prop key="java.naming.security.principal">admin</prop>
            <prop key="java.naming.security.credentials">admin</prop>
        </props>
    </property>
</bean>

<bean id="destination" class="com.tibco.tibjms.TibjmsQueue">
    <constructor-arg value="com.sample.queue" />
</bean>

监听器类是这样的:

public class MessageListenerApp implements MessageListener {

private static int c = 0;

@Override
public void onMessage(Message arg0) {

    try {
        System.out.println("Received Message..."+arg0.getStringProperty("MessageNum")+". Waiting to finish..");
        Thread.sleep(2000);
        System.out.println("Finished processing.."+arg0.getStringProperty("MessageNum")+".."+(c++));
    } catch (Exception e) {
        e.printStackTrace();
    }

}

}

我如何遵循从共享连接获得的会话应该明确关闭的建议?

遇到了 SessionAwareMessageListener 接口,该接口提供了提供 Session 句柄的 onMessage 方法。那么要正确实现会话关闭,应该实现这个接口吗?

4

2 回答 2

5

将缓存连接工厂与侦听器容器一起使用通常不是一个好主意,尤其是在使用maxConcurrentConsumers>时concurrentConsumers- 您最终可能会在缓存中使用缓存的消费者,这些消费者会在没有侦听器的情况下获取消息,并且此类消息可能会“卡住” ”。

因此,在这种情况下不要使用 a CCF,它实际上是用于生产者端的。

由于容器管理并发,会话/消费者是长期存在的,不需要缓存。

于 2013-09-18T03:38:41.757 回答
0

应用程序在使用DefaultMessageListenerContainer时不需要关闭会话,它会创建所需的会话并在关闭期间关闭它们。

根据我的理解,当应用程序使用 CachingConnectionFactory 参考创建 Session 时,您提到的注释适用于关于哪个弹簧不知道的参考。

于 2016-04-28T02:38:14.777 回答