我正在使用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);
}
我现在可以获得值,但我得到重复。
答案 0 :(得分:3)
由于您已修复配置(您正在接收消息),因此唯一需要解决的问题是您收到重复消息。这是由于你的配置这个部分:
<property name="concurrency" value="3-10"/>
如果你检查DefaultMessageListenerContainer的javadoc(JmsListenerContainerFactory扩展了),你会发现:
...对于某个主题,您通常会使用默认数字1 消费者,否则您将多次收到相同的消息 同一节点。
这是由于主题本身的架构,多个消费者将被视为需要接收已发送的每条消息的多个订阅者。
在解决方案方面:
您可能需要稍微修改一下代码。但大多数从Topic变为VirtualTopic的案例都可以胜任。 使用VirtualTopics,您可以获得&#34;类似队列&#34;消费者方面的行为,这意味着消息将被消费者消费,因此多个消费者不能两次看到相同的消息。
另一种选择当然是将并行处理工作负载转移到其他地方,在JMS入口点使用单个消费者。根据手头的任务,它也可能是一个充分的解决方案。