使用Spring JMS命名空间时未调用的方法

时间:2011-03-16 09:40:08

标签: java spring jms

我有一个基于Spring 3.0.5构建的应用程序,它使用JMS来交换消息。接收消息的bean使用jms命名空间进行配置。该课程看起来像这样

class MyService {
    public void receive(String msg) {
        ...
    }
}

Spring配置如下所示

<jms:listener-container destination-type="queue">
  <jms:listener destination="queue.test" ref="myService" method="receive"/>
</jms:listener-container>

但是,当我更改receive方法以获取Message对象时,不再调用该方法。

class MyService {
    public void receive(TextMessage msg) {
        ...
    }
}

我意识到我可以使用MessageListenerAdapter,但这是更多的配置开销,我只是想知道为什么这不起作用。

非常感谢任何见解。

2 个答案:

答案 0 :(得分:3)

<jms:listener>配置会自动为您创建MessageListenerAdapter,因此您无需明确配置它。

您的问题是MessageListenerAdapter旨在将您的代码与JMS API完全分离。 <jms:listener>中的目标方法必须声明MessageListenerAdapter允许的参数类型之一(请参阅docs),它代表消息的可能有效负载类型,即String之一,Serializablebyte[]Map

如果要接收原始JMS TextMessage对象,则侦听器类必须实现MessageListenerSessionAwareMessageListener。这使它成为一个“适当的”JMS监听器。在这种情况下,method配置变得多余,您可以使用:

<jms:listener destination="queue.test" ref="myService"/>

我真的很惊讶Spring发现你的receive方法的参数类型无效时没有抛出异常。

答案 1 :(得分:3)

我已经弄清楚,为了让MessageListenerAdapter 转换邮件,messageConverter属性必须设置为null 。但是,使用命名空间配置时,无法禁用自动创建的默认消息转换器。

AbstractListenerContainerParser中的代码检查message-converter的{​​{1}}属性是否未设置或指向有效的bean。否则,<jms:listener-container>被实例化。

要解决此问题,我已创建了SimpleMessageAdapter来解决问题

NoopMessageConverter

然后像这样配置public class NoopMessageConverter implements MessageConverter { @Override public Message toMessage(Object object, Session session) throws JMSException, MessageConversionException { return (Message) object; } @Override public Object fromMessage(Message message) throws JMSException, MessageConversionException { return message; } }

<jms:listener-container>

然后您可以按如下方式创建bean,并调用<bean id="noopMessageConverter" class="NoopMessageConverter"/> <jms:listener-container message-converter="noopMessageConverter"> <jms:listener destination="queue.test" ref="myService" method="receive"/> </jms:listener-container> 方法

receive