2

如果我使用DefaultMessageListenerContainerSpring接收JMS 消息,即使我设置sessionAcknowledgeMode为 2,我也不会重新传递 JMS 消息。

在我的 JavaBean 中的情况下,消息在 JMS 提供程序 ( ActiveMQ ) 中未得到确认RuntimeException在队列中保持挂起状态。但它永远不会重新交付,我认为这是由于 Spring 从不调用的事实造成的,根据ActiveMQ 的文档,需要重新交付才能发生。onMessage()session.recover()

任何人都可以给我一个提示,我可以如何配置在 RuntimeExceptions 的情况下DefaultMessageListenerContainer调用?session.recover()

最好的问候,
马丁

4

1 回答 1

3

您表明您正在使用 sessionAcknowledgeMode 2,即 Session.CLIENT_ACKNOWLEDGE。以下语句直接取自AbstractMessageListenerContainer Javadocs

  • "CLIENT_ACKNOWLEDGE":监听器执行成功后的自动消息确认;在抛出异常的情况下不重新投递。

所以问题不在于 Spring DMLC,它能够在抛出运行时异常时调用 Session.recover() 。您是否可以通过自己调用 Session.recover() 在侦听器的 onMessage() 方法中使用 try/catch 来处理运行时异常?

更新:

您对样板代码提出了很好的看法。它散布在许多地方并请求重构。你不可能抽象出这样的代码吗?这是一个常见的解决方案。使用包含 try/catch 和适当处理的方法创建一个抽象父类应该可以解决问题。然后只需扩展父类以根据需要实现尽可能多的自定义处理器。您甚至可以使用 Spring 应用程序上下文以适当的方式将处理器连接在一起。

我从来没有遇到过向应用程序添加特定于 Spring 的代码的问题,因为它可以在任何地方运行。当我开始使用 Spring 时,这对我来说很重要。它并不特定于任何单个应用程序服务器或 servlet 容器,因此如果我将 com.ibm 或 com.oracle 导入到我的源代码中,我不会像我那样使用 Spring 将自己编码到一个角落。事实上,我已经将 Spring JMS API 与一个 MOM 一起使用并切换到另一个 MOM,除了 JMS 连接工厂定义之外没有更改任何内容。

于 2010-02-03T16:40:18.540 回答