我正在尝试实现一个功能,其中我拥有的侦听器类可以订阅/取消订阅JMS主题。 经过一些研究后,我们没有看到明确的方法来做到这一点,我已经提出了两个解决方案:
jmsTemplate.receiveAndConvert(topicName)
(可能将阻塞操作本身委派给一个工作池)。
从主题订阅/取消订阅就像从列表中删除主题名称一样简单。有一个工厂类,它将为应用程序需要订阅的每个主题构建一个新的侦听器,使用如下方法:
public MessageListenerContainer createListener(String topic) {
DefaultMessageListenerContainer container = new DefaultMessageListenerContainer();
container.setConnectionFactory(connectionFactory());
container.setDestinationName(topic);
container.setMessageListener(new MyListenerClass());
return container;
}
第二种选择对我来说似乎更优雅,但我不确定听众的生命周期。我浏览了一下spring boot的jms和activemq模块的源代码,并注意到DefaultMessageListenerContainer
有方法initialize()
和start()
,但我不确定如何/如果我需要使用这些,因为我可以找到以这种方式构建MessageListenerContainer
的唯一方法是Bean
声明。
此外,当取消订阅主题时,因此想要销毁与之关联的侦听器容器,除了调用stop(callback)
方法之外还需要做更多的工作吗?
我对JMS / ActiveMQ及其Spring集成的理解是否正确,因为没有更简单的方法来实现这一点?我的方法是否正确?
答案 0 :(得分:2)
恕我直言,只要你
PooledConnectionFactory
)initialise()
和start()
,并stop()
取消订阅第二种方法一切都应该没问题
答案 1 :(得分:0)
要在运行时注册新的JmsListenerEndpoint
,您必须完成2个步骤
MessageListener
服务@Service
public class CustomMessageListener implements MessageListener {
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("[Custom message listener] " + textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
@Service
public class MessageListenersService {
@Autowired
private JmsListenerEndpointRegistry registry;
@Autowired
@Qualifier("containerFactory")
private DefaultJmsListenerContainerFactory factory;
public void registerListener(String queueNameToListen, MessageListener listener) {
SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
endpoint.setId("ep-"+listener.hashCode()); // ID is mandatory
endpoint.setMessageListener(listener);
endpoint.setDestination(queueNameToListen);
registry.registerListenerContainer(endpoint, factory, true);
}
}
private static final String CUSTOM_DESTINATION = "queue-42";
@Autowired
MessageListenersService messageListenersService;
@Autowired
CustomMessageListener customMessageListener;
@Autowired
JmsTemplate jmsTemplate;
@PostConstruct
public void createCustomListener() throws InterruptedException {
messageListenersService.registerListener(CUSTOM_DESTINATION, customMessageListener);
jmsTemplate.send(CUSTOM_DESTINATION, session -> session.createTextMessage("hello world"));
// wait your message:
TimeUnit.SECONDS.sleep(1);
}