Messaging is a way of communicating between entities. A sender sends a message to a messaging system, and also there can be one or multiple consumers listening to the queue to receive the messages. Messaging also makes the system loosely coupled as the sender and receiver are not communicating with each other directly. Also, the spring boot framework provides the required support to easily implement ActiveMQ producer-consumer application.
In this article, we will learn how to use the Apache ActiveMQ with Spring Boot for implementing the JMS(Java Messaging System) producer-consumer application.
Technologies used in this article are:
- Spring Boot version : 2.3.0.RELEASE
- Java version 1.8
- Apache ActiveMQ 5.15.13
Table of Contents
- Setting up the ActiveMQ
- Creating the producer application
- Creating the consumer application
- Testing the application
- Producer application
- Consumer application
- Conclusion
Setting up the ActiveMQ
We can download the latest version of the ActiveMQ installer from here.
On a Windows machine, we can start the server by running the .bat file from the extracted zip file. Navigate to the apache-activemq-x.xx.xx\bin\winxx directory and start the server by running the .bat file.
After starting the ActiveMQ server locally, we can access the Web console at http://localhost:8161.
The default username is admin, and the password is admin.
Once we log in successfully, we get the below screen.

Click on the Manage ActiveMQ broker link to open the ActiveMQ console window, as shown below.
Here, we can view the topics, queues, etc. We can also notice that currently, there are no messages in the queue.

Creating the producer application
Let us create a Spring Boot application that produces the message to the ActiveMQ message queue.
Create the application with required dependencies
Create a Spring Boot application with spring-boot-starter-activemq, spring-boot-starter-web, and lombok dependencies.
The Spring Boot ActiveMQ starter dependency also provides us the required auto-configuration along with an embedded in memory ActiveMQ server.
The dependencies we added to the pom.xml file are given below.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
Create a DTO class
Create a java DTO class with the name Student. We will use the student object as message content and also send that to the ActiveMQ message queue.
package com.asbnotebook.dto; import lombok.Getter; import lombok.Setter; import lombok.ToString; @Getter @Setter @ToString public class Student { private Integer id; private String name; }
Add required configuration
Create a spring configuration class with the name StudentConfiguration.
package com.asbnotebook.config; import javax.jms.ConnectionFactory; import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jms.config.DefaultJmsListenerContainerFactory; import org.springframework.jms.config.JmsListenerContainerFactory; import org.springframework.jms.support.converter.MappingJackson2MessageConverter; import org.springframework.jms.support.converter.MessageConverter; import org.springframework.jms.support.converter.MessageType; @Configuration public class StudentConfig { @Bean // Serialize message content to json using TextMessage public MessageConverter jacksonJmsMessageConverter() { MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); converter.setTargetType(MessageType.TEXT); converter.setTypeIdPropertyName("_asb_"); return converter; } }
- @Configuration: This annotation marks the class as a configuration class and adds it to the Spring application context.
- MessageConverter: We are using the MappingJackson2MessageConverter, and the target type is of Text format. The DTO object sent to the message queue in the JSON text format.
- TypeId: An id that should match both on the consumer and producer side. We can also set any value as TypeID.
Producing the message
Create a java class with the name StudentProducer.
Spring framework also provides a JmsTemplate that we can use to publish the message to the ActiveMQ message queue.
The convertAndSend() method serializes the object and sends it to the message queue.
package com.asbnotebook.jms; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jms.core.JmsTemplate; import org.springframework.stereotype.Component; import com.asbnotebook.dto.Student; import lombok.extern.slf4j.Slf4j; @Component @Slf4j public class StudentProducer { @Autowired private JmsTemplate jmsTemplate; public void sendTo(String destination, Student student) { jmsTemplate.convertAndSend(destination, student); log.info("Producer> Message Sent"); } }
Also, create a RESTful POST endpoint to send the Student object to the message queue.
This endpoint allows us to post the Student object to the message queue.
@SpringBootApplication public class SpringBootActivemqProducerExampleApplication { @Autowired StudentProducer studentProducer; @Value("${activemq.destination}") private String destination; public static void main(String[] args) { SpringApplication.run(SpringBootActivemqProducerExampleApplication.class, args); } @RestController public class StudentController { @PostMapping("/") public String sendMessage(@RequestBody Student student) { studentProducer.sendTo(destination, student); return "success"; } } }
Producer ActiveMQ configuration properties
Add the below configuration properties to the Spring Boot applications application.properties file.
spring.activemq.in-memory=false spring.activemq.broker-url=tcp://localhost:61616 spring.activemq.user=admin spring.activemq.password=admin activemq.destination=student
- spring.activemq.in-memory: Value is set to false, as we are using external ActiveMQ server.
- spring.activemq.broker-url: ActiveMQ broker URL.
- Also, set the Username and password if any is using the spring.activemq.user and spring.activemq.password configuration properties.
- activemq.destination: A queue/topic name to which the data is published.
Creating the consumer application
Create a consumer application with the required dependencies.
Use the same dependencies that we have used during the creation of the JMS producer application.
Copy the Student.java DTO class from the JMS publisher application.
Create a configuration class
Create a configuration class with the name StudentConfig.java
package com.asbnotebook.config; import javax.jms.ConnectionFactory; import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.jms.config.DefaultJmsListenerContainerFactory; import org.springframework.jms.config.JmsListenerContainerFactory; import org.springframework.jms.support.converter.MappingJackson2MessageConverter; import org.springframework.jms.support.converter.MessageConverter; import org.springframework.jms.support.converter.MessageType; @Configuration public class StudentConfig { @Bean public JmsListenerContainerFactory<?> jmsFactory(ConnectionFactory connectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setMessageConverter(jacksonJmsMessageConverter()); configurer.configure(factory, connectionFactory); return factory; } @Bean // Serialize message content to json using TextMessage public MessageConverter jacksonJmsMessageConverter() { MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); converter.setTargetType(MessageType.TEXT); converter.setTypeIdPropertyName("_asb_"); return converter; } }
- We have created a JmsContainerFactory bean and also set the message converter to our custom jacksonJmsConverter(). Even though this is not required, we can use this factory bean to customize the Jms listener(Like setting the error handling, etc.)
- The Message converter is a similar bean that we have created for producer application.
Creating the consumer
package com.asbnotebook.jms; import org.springframework.jms.annotation.JmsListener; import org.springframework.stereotype.Component; import com.asbnotebook.dto.Student; import lombok.extern.slf4j.Slf4j; @Component @Slf4j public class StudentConsumer { @JmsListener(destination = "${activemq.destination}", containerFactory = "jmsFactory") public void processToDo(Student student) { log.info("Consumer> " + student); } }
- @JmsListener: The method annotated with this annotation is a JMS listener method. The listener listens to the specified message queue/topic.
- destination: Name of the JMS topic/queue.
- containerFactory: This property specifies the custom container factory we have created earlier in the configuration class.
Consumer ActiveMQ configuration properties
These are the configuration properties that are similar to that of producer application configuration.
Update the server port number so that we can simultaneously start both producer and consumer applications.
spring.activemq.in-memory=false spring.activemq.broker-url=tcp://localhost:61616 spring.activemq.user=admin spring.activemq.password=admin activemq.destination=student server.port=8001
Testing the application
Both producer and consumer applications are ready now. With the ActiveMQ server running, let’s start testing the application.
Producer application
Start the producer Spring boot application. This application will run on default server port 8080.
As, we have a POST method, that allows us to pass the Student object as shown below.

Also, the ActiveMQ server console displays the published messages in the queue.

We can observe the message that is enqueued on the ActiveMQ server.

Consumer application
Finally, start the consumer Spring Boot application.
Once the application starts, it will consume the message from the ActiveMQ message queue.

Also, the ActiveMQ admin console displays the consumed messages under the dequeue column.

Conclusion
In this article, we learned how to use the Apache ActiveMQ to implement the JMS producer-consumer with the Spring Boot application.
Also, we created producer and consumer JMS applications using Spring Boot.
Then, we produced the messages from the producer application to the ActiveMQ message queue.
Finally, the consumer Spring Boot application consumed the published message from the ActiveMQ JMS queue.
The example code is available on GitHub.