使用@JmsListener监听ActiveMQ Artemis时,字符串主题发消息收不到
问题分析
你的问题根源在于Spring JmsTemplate的默认工作模式是点对点(Queue):
- 当传入
ActiveMQTopic对象时,JmsTemplate能识别这是主题类型,自动切换到发布订阅(Pub/Sub)模式发送消息; - 但直接传入字符串
"topicName"时,JmsTemplate默认会把它当作队列名称,消息会被发送到同名队列而非主题,而你的监听器是订阅主题的,自然收不到消息。
解决方案
有两种直接的解决方式,任选其一即可:
方式1:修改JmsTemplate配置,默认启用发布订阅模式
在jmsTemplate()方法中添加setPubSubDomain(true),让JmsTemplate默认以主题模式发送消息:
@Bean public JmsTemplate jmsTemplate() throws JMSException { JmsTemplate jmsTemplate = new JmsTemplate(jmsConnectionFactory()); jmsTemplate.setPubSubDomain(true); // 启用发布订阅模式 return jmsTemplate; }
这样无论你传入Topic对象还是字符串名称,JmsTemplate都会把目标当作主题处理。
方式2:使用指定目标类型的重载发送方法
如果你不想修改JmsTemplate的默认模式,可以使用convertAndSend的重载方法,明确指定发送到主题:
// 通过DestinationResolver指定目标为主题 jmsTemplate.convertAndSend("topicName", jsonMessage, m -> { m.setStringProperty("type", "new"); m.setStringProperty("sender", "abc"); return m; }, destination -> { return new org.apache.activemq.artemis.jms.client.ActiveMQTopic(destination); });
或者更简洁的方式,直接在发送时创建主题对象传入:
jmsTemplate.convertAndSend(new org.apache.activemq.artemis.jms.client.ActiveMQTopic("topicName"), jsonMessage, m -> { m.setStringProperty("type", "new"); m.setStringProperty("sender", "abc"); return m; });
补充说明
你的监听器配置是正确的,topicJmsListenerContainerFactory已经设置了setPubSubDomain(Boolean.TRUE),监听器会以主题订阅模式工作,只要消息正确发送到主题,就能被正常接收。
内容的提问来源于stack exchange,提问作者Tara
相关产品推荐
相关产品推荐

