如何在 Spring 4 中使用 @JmsListener 作为主题
How to use @JmsListener for topic in Spring 4
我正在使用 Spring 4.3.3,我正在尝试收听目标类型为主题的消息。
我可以在xml中实现:
<jms:listener-container connection-factory="connectionFactory"
destination-type="topic"
message-converter="jackson2MessageConverter">
<jms:listener destination="test.topic" ref="jmsTopicMessageListener1" method="receiveMessage"/>
<jms:listener destination="test.topic" ref="jmsTopicMessageListener2" method="receiveMessage"/>
</jms:listener-container>
但是我想使用@JmsListener。目前它仅适用于这样的队列目标:
@JmsListener(destination = "mailbox", containerFactory = "jmsListenerContainerFactory")
public void receiveMessage(DataObject dataObject) {
System.out.println("Received <" + dataObject.getName() + ">");
}
如何收听带有此注释@JmsListener 的主题?
提前致谢。
更新:
我已经在配置中试过了:
<bean id="topicJmsListenerContainerFactory"
class="org.springframework.jms.config.DefaultJmsListenerContainerFactory">
<property name="connectionFactory" ref="cachingConnectionFactory"/>
<property name="destinationResolver" ref="jmsDestResolver"/>
<property name="concurrency" value="3-10"/>
<property name="messageConverter" ref="jackson2MessageConverter"/>
<property name="pubSubDomain" value="true"/>
</bean>
然后这个:
@JmsListener(destination = "test.topic", containerFactory = "topicJmsListenerContainerFactory")
public void receiveMessage(DataObject dataObject) {
System.out.println("Received <" + dataObject.getName() + ">" + 1);
}
我现在可以获取值,但我得到了重复项。
既然你已经修复了你的配置(你正在接收消息),那么唯一需要解决的问题就是你正在接收重复的消息。这是由于您的这部分配置:
<property name="concurrency" value="3-10"/>
如果您检查 DefaultMessageListenerContainer(JmsListenerContainerFactory 扩展)的 javadoc,您会发现:
...for a topic, you will typically stick with the default number of 1
consumer, otherwise you'd receive the same message multiple times on
the same node.
这是由于主题本身的架构,多个消费者将被视为多个订阅者,他们需要接收每条已发送的消息。
在解决方案方面:
您可能需要稍微构建一下您的代码。但大多数情况下,从 Topic 更改为 VirtualTopic 都可以完成这项工作。 借助 VirtualTopics,您可以在消费者方面获得 "Queue-like" 行为,这意味着消息将被消费者消费,因此多个消费者无法看到同一条消息两次。
当然,另一种选择是将并行处理工作负载转移到其他地方,在 JMS 入口点使用单个使用者。根据手头的任务,它也可能是一个足够的解决方案。
我正在使用 Spring 4.3.3,我正在尝试收听目标类型为主题的消息。
我可以在xml中实现:
<jms:listener-container connection-factory="connectionFactory"
destination-type="topic"
message-converter="jackson2MessageConverter">
<jms:listener destination="test.topic" ref="jmsTopicMessageListener1" method="receiveMessage"/>
<jms:listener destination="test.topic" ref="jmsTopicMessageListener2" method="receiveMessage"/>
</jms:listener-container>
但是我想使用@JmsListener。目前它仅适用于这样的队列目标:
@JmsListener(destination = "mailbox", containerFactory = "jmsListenerContainerFactory")
public void receiveMessage(DataObject dataObject) {
System.out.println("Received <" + dataObject.getName() + ">");
}
如何收听带有此注释@JmsListener 的主题?
提前致谢。
更新:
我已经在配置中试过了:
<bean id="topicJmsListenerContainerFactory"
class="org.springframework.jms.config.DefaultJmsListenerContainerFactory">
<property name="connectionFactory" ref="cachingConnectionFactory"/>
<property name="destinationResolver" ref="jmsDestResolver"/>
<property name="concurrency" value="3-10"/>
<property name="messageConverter" ref="jackson2MessageConverter"/>
<property name="pubSubDomain" value="true"/>
</bean>
然后这个:
@JmsListener(destination = "test.topic", containerFactory = "topicJmsListenerContainerFactory")
public void receiveMessage(DataObject dataObject) {
System.out.println("Received <" + dataObject.getName() + ">" + 1);
}
我现在可以获取值,但我得到了重复项。
既然你已经修复了你的配置(你正在接收消息),那么唯一需要解决的问题就是你正在接收重复的消息。这是由于您的这部分配置:
<property name="concurrency" value="3-10"/>
如果您检查 DefaultMessageListenerContainer(JmsListenerContainerFactory 扩展)的 javadoc,您会发现:
...for a topic, you will typically stick with the default number of 1 consumer, otherwise you'd receive the same message multiple times on the same node.
这是由于主题本身的架构,多个消费者将被视为多个订阅者,他们需要接收每条已发送的消息。
在解决方案方面:
您可能需要稍微构建一下您的代码。但大多数情况下,从 Topic 更改为 VirtualTopic 都可以完成这项工作。 借助 VirtualTopics,您可以在消费者方面获得 "Queue-like" 行为,这意味着消息将被消费者消费,因此多个消费者无法看到同一条消息两次。
当然,另一种选择是将并行处理工作负载转移到其他地方,在 JMS 入口点使用单个使用者。根据手头的任务,它也可能是一个足够的解决方案。