I am trying to implement a functionality where a listener class I have can subscribe/unsubscribe to JMS topics. After some research there doesn't see to be a clear way to do this and I've come up with two solutions:
jmsTemplate.receiveAndConvert(topicName)
on each (probably delegating the blocking operation itself to a worker pool). Subscribing/Unsubscribing from a topic would be as simple as removing a topic name from the list.Have a factory class which would build a new listener for each topic the application needs to subscribe to, using a method like:
public MessageListenerContainer createListener(String topic) { DefaultMessageListenerContainer container = new DefaultMessageListenerContainer(); container.setConnectionFactory(connectionFactory()); container.setDestinationName(topic); container.setMessageListener(new MyListenerClass()); return container;
}
The second option seems more elegant to me, but I am unsure of the lifecycle of the listeners. I went through a bit of the source for spring boot's jms and activemq modules and noticed that DefaultMessageListenerContainer
has methods initialize()
and start()
though I'm unsure how/if I need to use these, as the only way I could find a MessageListenerContainer
being built this way is as a Bean
declaration. Also when unsubscribing from a topic, therefore wanting to destroy the listener container associated with it, is there more that needs to be done except calling the stop(callback)
method?
Is my understanding of JMS/ActiveMQ and its Spring integration correct in that there is no simpler way to achieve this? Is my approach correct?
IMHO as long as you
PooledConnectionFactory
one)initialise()
and start()
on subscription and stop()
to unsuscribeeverything should be fine with the second approach
To register new JmsListenerEndpoint
in runtime you must complete 2 steps
MessageListener
service @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);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.