@JmsListener using a subscription topic

I am trying to create an example for publishing-subscribe based on @JmsListener annotation: https://github.com/lkrnac/book-eiws-code-samples/tree/master/05-jms/0515-publish-subscribe

Relevant code fragments:

@Slf4j @SpringBootApplication @EnableScheduling public class JmsPublishSubscribeApplication { public static void main(String[] args) throws InterruptedException { SpringApplication.run(JmsPublishSubscribeApplication.class, args); } @Bean public ActiveMQTopic simpleTopic() { return new ActiveMQTopic("simpleTopic"); } } @Component public class SimpleMessageListener1 { @JmsListener(destination = "simpleTopic") public void readMessage(String message) { //.... } } @Component public class SimpleMessageListener2 { @JmsListener(destination = "simpleTopic") public void readMessage(String message) { //.... } } 

The problem is that this behavior is obtained:

 2015-05-17 20:07:04.985 INFO 22983 --- [pool-1-thread-1] nlbechapter05.SimpleMessageSender : Sending message: simple message 2015-05-17 20:07:05.070 INFO 22983 --- [enerContainer-1] nlbecJmsPublishSubscribeApplication : Message Received: simple message via listener 2 2015-05-17 20:07:05.975 INFO 22983 --- [pool-1-thread-1] nlbechapter05.SimpleMessageSender : Sending message: simple message 2015-05-17 20:07:05.986 INFO 22983 --- [enerContainer-1] nlbecJmsPublishSubscribeApplication : Message Received: simple message via listener 1 2015-05-17 20:07:06.975 INFO 22983 --- [pool-1-thread-1] nlbechapter05.SimpleMessageSender : Sending message: simple message 2015-05-17 20:07:06.987 INFO 22983 --- [enerContainer-1] nlbecJmsPublishSubscribeApplication : Message Received: simple message via listener 2 2015-05-17 20:07:07.975 INFO 22983 --- [pool-1-thread-1] nlbechapter05.SimpleMessageSender : Sending message: simple message 2015-05-17 20:07:07.994 INFO 22983 --- [enerContainer-1] nlbecJmsPublishSubscribeApplication : Message Received: simple message via listener 1 

But each message should be consumed by both listeners by topic definition. What am I missing?

+8
spring spring-jms
source share
2 answers

When using @JmsListener it uses the @JmsListener , which extends the JmsDestinationAccessor , which defaults to pubSubDomain false . When this property is false, it runs in the queue. If you want to use themes, you must set this property to true .

When you use Spring Boot , you can easily set this property to true by adding the spring.jms.pub-sub-domain property to application.properties and set it to true .

 spring.jms.pub-sub-domain=true 

When using @JmsListener it searches for a jmsListenerContainerFactory named bean if it is unavailable by default one is expected. You can also enable your own bean and programmatically set this property yo true .

 @Bean public DefaultMessageListenerContainer jmsListenerContainerFactory() { DefaultMessageListenerContainer dmlc = new DefaultMessageListenerContainer(); dmlc.setPubSubDomain(true); // Other configuration here return dmlc; } 

This, of course, will work, but there will be more work, more information on this can be found in the @EnableJms documentation annotation .

+21
source share

Switching the default destination type @JmsListener from Queue to Topic can be done entirely in Java without changing properties or using XML.

The Spring guide provides an example of setting default options provided by the DefaultMessageListenerContainer .

To do this, define the user bean as follows:

 @Bean public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); // This provides all boot default to this factory, including the message converter configurer.configure(factory, connectionFactory); // You could still override some of Boot default if necessary. factory.setPubSubDomain(true); return factory; } 

This can then be used in the annotated @JmsListener method:

 @JmsListener(destination = "mailbox", containerFactory = "myFactory") public void receiveMessage(Email email) { // implementation } 
+4
source share

All Articles