Home  >  Spring 5

Spring JMS Topic Listener Example

By Arvind Rai, August 30, 2020
This page will walk through Spring JMS topic listener example. To listen topic, we need to enable publish/subscribe functionality. By default JMS messaging is performed for point-to-point to listen queue.
Here in our example we will create listener using @JmsListener and publish message using JmsTemplate.

Technologies Used

Find the technologies being used in our example.
1. Java 11
2. Spring 5.2.8.RELEASE
3. Spring Boot 2.3.2.RELEASE
4. Maven 3.5.2

Enable Publish/Subscribe

By default publish and subscribe for a topic is set to false and only queue can be sent and received. We can enable publish/subscribe in following ways.
1. Using application.properties in Spring Boot application.
spring.jms.pub-sub-domain=true 
The default value of above property is false. To listen topic by more than one listeners, we need to pass true value to above property.

2. Using Java configuration file.
@Bean
public DefaultJmsListenerContainerFactory jmsContainerFactory() {
	DefaultJmsListenerContainerFactory containerFactory = new DefaultJmsListenerContainerFactory();
	containerFactory.setPubSubDomain(true);
    ------
	return containerFactory;
} 
The default value for setPubSubDomain() is false. We need to pass true value to enable publish/subscribe for a topic.

Creating Listener with @JmsListener

The @JmsListener annotation marks a method to be a JMS message listener for the specified destination. To enable @JmsListener, we need to annotate our Java configuration class with @EnableJms annotation. Find the sample lsiteners.
@JmsListener(destination = "spring", containerFactory = "jmsContainerFactory")
public void receiveMessage1(News news) {
   ------
}
@JmsListener(destination = "spring", containerFactory = "jmsContainerFactory")
public void receiveMessage2(News news) {
   ------
} 

Publishing Topic using JmsTemplate

The JmsTemplate is the helper class to send, receive and convert JMS messages. In our code snippet, we are publishing a topic that will be received by listeners with specified destination as spring.
Topic springTopic = jmsTemplate.getConnectionFactory().createConnection()
   	   .createSession().createTopic("spring");
jmsTemplate.convertAndSend(springTopic, news); 

Complete Example

pom.xml
<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.3.2.RELEASE</version>
	<relativePath />
</parent>
<dependencies>
        <dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-activemq</artifactId>
	</dependency>
	<dependency>
		<groupId>org.apache.activemq</groupId>
		<artifactId>activemq-broker</artifactId>
	</dependency>
	<dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-databind</artifactId>
	</dependency>
</dependencies> 
JMSConfig.java
package com.concretepage.config;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessageType;
@Configuration
@EnableJms
public class JMSConfig {
	@Bean
	public DefaultJmsListenerContainerFactory jmsContainerFactory() {
		DefaultJmsListenerContainerFactory containerFactory = new DefaultJmsListenerContainerFactory();
		containerFactory.setPubSubDomain(true);
		containerFactory.setConnectionFactory(connectionFactory());
		containerFactory.setMessageConverter(jacksonJmsMessageConverter());
		return containerFactory;
	}
	@Bean
	public CachingConnectionFactory connectionFactory() {
		CachingConnectionFactory cachConnectionFactory = new CachingConnectionFactory();
		ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory();
		connectionFactory.setBrokerURL("tcp://localhost:61616");
		cachConnectionFactory.setTargetConnectionFactory(connectionFactory);
		return cachConnectionFactory;
	}
	@Bean
	public MessageConverter jacksonJmsMessageConverter() {
		MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
		converter.setTargetType(MessageType.TEXT);
		converter.setTypeIdPropertyName("_type");
		return converter;
	}
} 
NewsReceiver1.java
package com.concretepage.receiver;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import com.concretepage.News;
@Component
public class NewsReceiver1 {
	@JmsListener(destination = "spring", containerFactory = "jmsContainerFactory")
	public void receiveNews(News news) {
		System.out.println("Receiver1: " + news);
	}
} 
NewsReceiver2.java
package com.concretepage.receiver;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import com.concretepage.News;
@Component
public class NewsReceiver2 {
	@JmsListener(destination = "spring", containerFactory = "jmsContainerFactory")
	public void receiveMessage(News news) {
		System.out.println("Receiver2: " + news);
	}
} 
News.java
package com.concretepage;
public class News {
	private int id;
	private String title;
	public News() {}
	public News(int id, String title) {
		this.id = id;
		this.title = title;
	}	
        //Sets and Gets        

	@Override
	public String toString() {
		return id + ", " + title;
	}
} 
Application.java
package com.concretepage;
import javax.jms.JMSException;
import javax.jms.Topic;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.jms.JmsException;
import org.springframework.jms.core.JmsTemplate;
@SpringBootApplication
public class Application {
	public static void main(String[] args) throws JmsException, JMSException {
		ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
		JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);
		Topic springTopic = jmsTemplate.getConnectionFactory().createConnection()
				.createSession().createTopic("spring");
		News news = new News(100, "Latest news on Spring");
		jmsTemplate.convertAndSend(springTopic, news);
	}
} 
Find the print screen of the output in Eclipse console.
Spring JMS Topic Listener Example

References

JMS (Java Message Service)
Spring @JmsListener

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI








©2020 concretepage.com | Privacy Policy | Contact Us