Java 使用SpringJMS命名空间时未调用方法
我有一个基于Spring3.0.5构建的应用程序,它使用JMS交换消息。通过使用Java 使用SpringJMS命名空间时未调用方法,java,spring,jms,Java,Spring,Jms,我有一个基于Spring3.0.5构建的应用程序,它使用JMS交换消息。通过使用jms名称空间配置接收消息的bean。这个班看起来像这样 class MyService { public void receive(String msg) { ... } } <jms:listener-container destination-type="queue"> <jms:listener destination="queue.test" ref=
jms
名称空间配置接收消息的bean。这个班看起来像这样
class MyService {
public void receive(String msg) {
...
}
}
<jms:listener-container destination-type="queue">
<jms:listener destination="queue.test" ref="myService" method="receive"/>
</jms:listener-container>
<bean id="noopMessageConverter" class="NoopMessageConverter"/>
<jms:listener-container message-converter="noopMessageConverter">
<jms:listener destination="queue.test" ref="myService" method="receive"/>
</jms:listener-container>
Spring配置如下所示
class MyService {
public void receive(String msg) {
...
}
}
<jms:listener-container destination-type="queue">
<jms:listener destination="queue.test" ref="myService" method="receive"/>
</jms:listener-container>
<bean id="noopMessageConverter" class="NoopMessageConverter"/>
<jms:listener-container message-converter="noopMessageConverter">
<jms:listener destination="queue.test" ref="myService" method="receive"/>
</jms:listener-container>
我意识到我可以只使用MessageListenerAdapter
,但这会增加配置开销,我只是想知道为什么这不起作用
非常感谢您的任何见解
Frank配置会自动为您创建一个MessageListenerAdapter
,因此您无需显式配置
您的问题是MessageListenerAdapter
的设计目的是将您的代码与JMS API完全解耦。
中的目标方法必须声明MessageListenerAdapter
(请参阅)允许的参数类型之一,该参数类型表示消息的可能负载类型,即字符串
、可序列化
、字节[]
或映射
中的一种
如果希望接收原始JMSTextMessage
对象,则侦听器类必须实现MessageListener
或SessionAwareMessageListener
。这使它成为一个“合适的”JMS侦听器。在这种情况下,方法
配置变得多余,您只需使用:
<jms:listener destination="queue.test" ref="myService"/>
实际上,我很惊讶Spring在发现您的
receive
方法的参数类型无效时没有抛出异常。我发现,要使MessageListenerAdapter
不转换消息,必须将messageConverter
属性设置为null
。但是,在使用名称空间配置时,无法禁用自动创建的默认消息转换器
AbstractListenerContainerParser
中的代码检查
的消息转换器
属性是否未设置或指向有效bean。否则将实例化一个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;
}
}
然后像这样配置
class MyService {
public void receive(String msg) {
...
}
}
<jms:listener-container destination-type="queue">
<jms:listener destination="queue.test" ref="myService" method="receive"/>
</jms:listener-container>
<bean id="noopMessageConverter" class="NoopMessageConverter"/>
<jms:listener-container message-converter="noopMessageConverter">
<jms:listener destination="queue.test" ref="myService" method="receive"/>
</jms:listener-container>
关键是
MessageListenerAdapter
完全能够调用一个需要原始Message
对象的方法。这些文档甚至包含一个带有DefaultTextMessageDelegate
的示例。在我的情况下,我需要访问消息属性。实现MessageListener
接口意味着该类中只能有一个方法,然后需要将传入消息从多个队列分派到其他方法。我猜
配置了默认的MessageListenerAdapter
,但为了获取原始消息,可能需要禁用内容通过将消息转换器设置为null
进行提取。然而,这在
中似乎是不可能的。