使用Spring MessageListener来消费组中的消息?

时间:2012-08-30 00:09:23

标签: java spring jms activemq

我有一个spring应用程序,我想使用JMS Message Groups来处理特定块中的JMS消息(以及相同的事务等)。基本上我说我有5个相关事件,我有一个JMSTemplate,它们使用相同的JMSXGroupID和顺序JMSXGroupSeq值发送它们。

然后我在Spring中定义了MessageProcessorService看起来像这样:

<bean id="messageProcessorService" class="x.y.z.MessageProcessorService"/>
<jms:listener-container connection-factory="pooledJmsConnectionFactory" concurrency="5" >
    <jms:listener destination="messages.queue" ref="messageProcessorService" />
</jms:listener-container>

我的MessageProcessorService是标准的,简单的:

@Service
public class MessageProcessorService implements MessageListener {

public void onMessage(Message msg) { ... }
}

问题是,因为onMessage只能获得1条消息。如何获取特定组中的所有5条消息,然后开始处理它们?

我知道我可以使用负JMSXGroupSeq值来标记组的结尾,然后我想我可以保留一小部分消息并检查消息JMSXGroupSeq以及何时消息-1然后处理整个组,但这似乎有点hacky并且不确定它是否是线程安全的(我肯定需要并行处理多个线程)。

其他人在Spring / JMS / ActiveMQ之前做过类似的事情吗?

2 个答案:

答案 0 :(得分:1)

为了回答我自己的问题,我找到了this approach并做了大致相似的事情。虽然不是很漂亮。我认为从长远来看,我们可能不得不放弃MessageListenerContainer并使用直接JMS api推出我们自己的解决方案。

答案 1 :(得分:0)

好问题。虽然消息组对某些任务很有用,但它们并没有将这些好处映射到消息监听器上。

您可以采用自己的方法,在邮件的内存中保留一个列表。如果在原型范围中创建Listener bean,则线程安全性不会成为问题。

<bean id="messageProcessorService" class="x.y.z.MessageProcessorService" scope="prototype"/>

http://static.springsource.org/spring/docs/3.0.7.RELEASE/reference/beans.html#beans-factory-scopes-prototype

您只需要保留在课程中收到的一些内部消息列表,它们对于该线程将是唯一的。

这取决于您的交易要求。您是否需要围绕整个消息组提交事务?然后你需要跟踪何时提交以及何时提交。 IBM已经在清单5中举例说明了这一点(尽管不使用ActiveMQ)here。它不是Spring而是普通的MDB。不能说它与ActiveMQ的工作原理相同,所以我不保证。