In this tutorials, I am going to show how to work with the most popular and powerful open source messaging server Apache ActiveMQ with a Spring Boot application.
In the previous tutorials, we have seen how to use in-memory activemq in spring boot. Here we will see Standalone/External Apache ActiveMQ with Spring Boot.
Download Apache ActiveMQ:
Download the latest Apache ActiveMQ from the official portal, for me, it is 5.15.7.
Download the latest ActiveMQ Release by clicking on the above windows distribution. It will be downloaded as a .zip file and extract it where ever you like in your system.
Got to Apache-ActiveMQ-X.X.X/bin/win64 folder where you can see activemq.batch file.
Double click on that file to run ActiveMQ instance on your windows machine. Now you can see the Apache ActiveMQ admin console with the below URL with default ActiveMQ port.
http://localhost:8161/admin/connections.jsp
Here you can observe there are no active connections at all and also go and check Topic and Queue tabs there also you can see zero topics and zero queue size because we never push any messages to ActiveMQ yet.
That’s it for now, just keep this window aside for a while, and let’s see how can we access this standalone ActiveMQ in Spring Boot Application and send some messages to it.
Apache ActiveMQ Spring Boot Example:
As part of this example, I am going to create a rest service with a simple rest endpoint which takes a message and push the message to ActiveMQ server and also creating a consumer which consumes the messages from ActiveMQ server, as soon as the ActiveMQ server get updated with a message.
Technologies:
- Spring Boot 2.1.0
- Apache ActiveMQ 5.15.7
- Java8
- IntelliJ Idea
Application Structure:
Project Dependencies:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.onlinetutorialspoint</groupId>
<artifactId>SpringBoot-External_ActiveMq-Example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>SpringBoot-External_ActiveMq-Example</name>
<description>External Apache ActiveMQ Spring Boot Example</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Creating JMS ActiveMQ configuration.
- Creating JMS Queue with the name of simple-jms-queue.
- Creating ActiveMQConnectionFactory with external ActiveMQ broker URL (which will read from the properties file)
- Creating JmsTemplate using ActiveMQConnectionFactory
package com.onlinetutorialspoint.config;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQQueue;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.core.JmsTemplate;
import javax.jms.Queue;
@Configuration
@EnableJms
public class JMSConfig {
@Value("active-mq-url")
private String activeMqUrl;
@Bean
public Queue queue(){
return new ActiveMQQueue("simple-jms-queue");
}
@Bean
public ActiveMQConnectionFactory connectionFatory(){
ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
factory.setBrokerURL(activeMqUrl);
return factory;
}
@Bean
public JmsTemplate jmsTemplate(){
return new JmsTemplate(connectionFatory());
}
}
application properties.
- Running the application on 8080 port
- By default the in-memory ActiveMQ got enabled when we define ActiveMQ dependencies in pom.xml, As we are using external ActiveMQ instance we should disable it by saying spring.activemq.in-memory=false and spring.activemq.pool.enable=false
- Providing external ActiveMQ URL, this may be external system URL or local. Currently, my ActiveMQ running under the same machine so that I provided as localhost:61616 whereas 61616 is the default ActiveMQ port.
server.port=8080
spring.activemq.in-memory=false
spring.activemq.pool.enable=false
active-mq-url=tcp://localhost:61616
Creating Spring Boot Rest end-point to publish some messages to ActiveMQ.
package com.onlinetutorialspoint.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import javax.jms.Queue;
@RestController
public class Producer {
@Autowired
private Queue queue;
@Autowired
private JmsTemplate jmsTemplate;
@GetMapping("publish/{msg}")
public String publish(@PathVariable("msg") final String msg){
jmsTemplate.convertAndSend(queue,msg);
return "Your message <b>"+msg+"</b> published successfully";
}
}
JmsTemplate is a helper class that simplifies receiving and sending of messages through JMS and gets rid of the boilerplate code.
Creating a JmsListener.
The JmsListener listens on the given JMS queue (simple-jms-queue) whenever the queue get updated with a message it will get notified.
package com.onlinetutorialspoint.listener;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
@Component
public class Consumer {
@JmsListener(destination = "simple-jms-queue")
public void listener(String msg){
System.out.println("Received Message : "+msg);
}
}
Spring Boot Main class.
package com.onlinetutorialspoint;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootActiveMqInMemoryExampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootActiveMqInMemoryExampleApplication.class, args);
}
}
Run it.
mvn spring-boot:run
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.0.RELEASE)
2018-11-03 15:05:06.830 INFO 9344 --- [ main] ngBootExternalActiveMqExampleApplication : Starting SpringBootExternalActiveMqExampleApplication on DESKTOP-RN4SMHT with PID 9344 (E:\work\SpringBoot-External_ActiveMq-Example\target\classes started by Lenovo in E:\work\SpringBoot-External_ActiveMq-Example)
2018-11-03 15:05:06.857 INFO 9344 --- [ main] ngBootExternalActiveMqExampleApplication : No active profile set, falling back to default profiles: default
2018-11-03 15:05:11.525 INFO 9344 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
....
....
Publish message
http://localhost:8080/publish/Hello%20Chandra
The message got published successfully. Let’s see our ActiveMQ admin console.
There we can see our simple-jms-queue name in topics and currently it is in the queue.
Note: For better understanding, I commented the consumer code in the application and ran it, so that we can see the queued messages in the ActiveMQ console.
Let me re-run the application by uncommenting the consumer code.
Now we can see the console output as Received Message: Hello Chandra
Let’s check ActiveMQ console now, the message should be dequeued.
Reference:
Happy Learning 🙂