Boot

Spring Boot and RabbitMQ Hello World Example

Welcome readers, in this tutorial, we will see how to implement a simple hello world application with Spring Boot and RabbitMQ.

1. Introduction

Before going further in this tutorial we will take a look at the common terminology such as introduction to Spring Boot and RabbitMQ.

1.1 What is Spring boot?

  • Spring boot is a module that provides rapid application development feature to the spring framework including auto-configuration, standalone-code, and production-ready code
  • It creates applications that are packaged as jar and are directly started using embedded servlet container (such as Tomcat, Jetty or Undertow). Thus, no need to deploy the war files
  • It simplifies the maven configuration by providing the starter template and helps to resolve the dependency conflicts. It automatically identifies the required dependencies and imports them in the application
  • It helps in removing the boilerplate code, extra annotations, and XML configurations
  • It provides a powerful batch processing and manages the rest endpoints
  • It provides an efficient JPA-starter library to effectively connect the application with the relational databases
  • It offers a Microservice architecture and cloud configuration that manages all the application related configuration properties in a centralized manner.

1.2 What is RabbitMQ & When is often used?

  • It is an AMQP messaging broker and is the famously easy to set up, open-source, and cross-platform message broker
    • AMQP stands for Advanced Message Queuing protocol which offers features like Message Orientation, Queuing, Routing (through Point-to-Point or Publish-and-Subscribe), Reliability and Security
  • It offers an easy way to exchange different platform applications (like Java and DotNet) and offers helps in communication between different Microservices
  • It is a lightweight and easy to deploy application available on-premises and cloud to meet the high scalability and availability requirements
  • In the present time, a single application supports multiple tasks (i.e. sending notifications, reports, etc.). So sometimes these tasks add an extra load on the application thereby increasing the maintenance cost (such as space, memory, etc) to serve more requests. Thus, RabbitMQ in such situations acts a blessing to remove some of the heavy tasks
Fig. 1: RabbitMQ basic flow diagram

In case readers are interested to read through the detailed theory on RabbitMQ they can read the tutorial present at this link.

2. Spring Boot and RabbitMQ Hello World Example

Here is a systematic guide for implementing this tutorial but before going any further I’m assuming that readers are aware of the Spring boot and RabbitMQ basics.

2.1 Application Pre-requisite

To start with this tutorial, we are hoping that readers at present have the RabbitMQ up and running on their local environment. For easy setup, the reader can have the RabbitMQ up and running on the Docker environment. If someone needs to go through the RabbitMQ installation on Docker, please watch this video.

2.2 Tools Used for Spring boot application and Project Structure

We are using Eclipse, JDK 8, and Maven. In case you’re confused about where you should create the corresponding files or folder, let us review the project structure of the spring boot application.

spring boot rabbitmq - Project structure
Fig. 2: Project structure

Let us start building the application!

3. Creating a Spring boot application

Below are the steps involved in developing the application.

3.1 Maven Dependency

Here, we specify the dependency for the Spring Boot and RabbitMQ. Maven will automatically resolve the other dependencies. The updated file will have the following code.

pom.xml

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.springboot.rabbitmq</groupId>
	<artifactId>Springbootrabbitmqtutorial</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.2.RELEASE</version>
	</parent>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-amqp</artifactId>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>

		<finalName>Spring-Boot-Rabbitmq</finalName>
	</build>
</project>

3.2 Application Properties file

Create a new properties file at the location: Springbootrabbitmqtutorial/src/main/resources/ and add the RabbitMQ and Queue configuration details.

application.properties

## Spring boot application name
spring.application.name=RabbitMqOnSpringboot

## Application port
server.port=9091

## Rabbitmq configuration
spring.rabbitmq.host=<!-- RABBITMQ_HOST -->
spring.rabbitmq.port=<!-- RABBITMQ_PORT_NUMBER -->
spring.rabbitmq.username=<!-- RABBITMQ_USERNAME -->
spring.rabbitmq.password=<!-- RABBITMQ_PASSWORD -->

## Queue and exchange configuration properties for rabbitmq
rabbitmq.queue=queue1
rabbitmq.exchange=jcg-exchange
rabbitmq.routingkey=routingkey1

3.3 Java Classes

Let us write all the java classes involved in this application.

3.3.1 Implementation/Main class

Add the following code to the main class to bootstrap the application from the main method.

SpringbootRabbitmq.java

package com.jcg.springboot.rabbitmq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// @SpringBootApplication annotation enables the auto-configuration feature of the spring boot module (i.e. java-based configuration and component scanning).
@SpringBootApplication
public class SpringbootRabbitmq {

	private static final Logger LOGGER = LoggerFactory.getLogger(SpringbootRabbitmq.class);
	
	public static void main(String[] args) {
		// The "run()" method returns the "ConfigurableApplicationContext" instance which can be further used by the spring application.
		SpringApplication.run(SpringbootRabbitmq.class, args);
		LOGGER.info("Springboot application with rabbitmq started successfully.");
	}
}

3.3.2 Configuration class

Add the following code to the configuration class where we map the Queue properties from the properties file and define the configuration for RabbitMQ.

RabbitMqConfig.java

package com.jcg.springboot.rabbitmq.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

// Marker annotation that tells spring to generate bean definitions at runtime for the methods annotated with @Bean annotation.
@Configuration
public class RabbitMqConfig {

	// Value is populated with the queue name from "application.properties" file.
	@Value("${rabbitmq.queue}")
	private String queueName;
	
	// Value is populated with the exchange name from "application.properties" file.
	@Value("${rabbitmq.exchange}")
	private String exchange;
	
	// Value is populated with the routing key from "application.properties" file.
	@Value("${rabbitmq.routingkey}")
	private String routingKey;

	// @Bean annotation tells that a method produces a bean which is to be managed by the spring container.
	@Bean
	Queue queue() {
		// Creating a queue.
		return new Queue(queueName, Boolean.FALSE);
	}

	@Bean
	TopicExchange topicExchange() {
		// Creating a topic exchange.
		return new TopicExchange(exchange);
	}

	@Bean
	Binding binding(final Queue queue, final TopicExchange topicExchange) {
		// Binding the queue to the topic with a routing key.
		return BindingBuilder.bind(queue).to(topicExchange).with(routingKey);
	}
}

3.3.3 Controller class

Add the following code to the controller class designed to handle the incoming requests. The class is annotated with the @RestController annotation which consists of the HTTP GET method that receives the user input and publishes the message to the queue.

Publisher.java

package com.jcg.springboot.rabbitmq.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

// For creating the REST controllers.
@RestController
// Used to map incoming web requests onto the handler methods in the controller.
@RequestMapping(value = "/api")
public class Publisher {

	private static final Logger LOGGER = LoggerFactory.getLogger(Publisher.class);

	// TODO - 
	@Autowired
	RabbitTemplate rabbitTemplate;
	@Autowired
	Binding binding;

	// HTTP GET url - http://localhost:9091/api/send/{msg}
	@GetMapping(value = "/send/{msg}")
	// @ResponseStatus annotation marks the method with the status-code and the reason message that should be returned.
	@ResponseStatus(code = HttpStatus.OK)
	public String send(@PathVariable("msg") final String message) {
		LOGGER.info("Sending message to the queue.");
		rabbitTemplate.convertAndSend(binding.getExchange(), binding.getRoutingKey(), message);
		LOGGER.info("Message sent successfully to the queue, sending back the response to the user.");
		return "Message sent successfully to the queue.";
	}
}

3.3.4 Subscriber class

Add the following code to the Subscriber class which has a method bonded to the queue with the help of @RabbitListener annotation and listen to the message coming to the queue.

Subscriber.java

package com.jcg.springboot.rabbitmq.listen;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Subscriber {

	private static final Logger LOGGER = LoggerFactory.getLogger(Subscriber.class);

	@Autowired
	Queue queue;

	@RabbitListener(queues = "#{queue.getName()}")	// Dynamically reading the queue name using SpEL from the "queue" object.
	public void receive(final String message) {
		LOGGER.info("Listening messages from the queue!!");
		LOGGER.info("Received the following message from the queue= " + message);
		LOGGER.info("Message received successfully from the queue.");
	}
}

4. Run the Application

To execute the application, right-click on the SpringbootRabbitmq.java class, Run As -> Java Application.

spring boot rabbitmq - Run the Application
Fig. 3: Run the Application

5. Project Demo

Open the Postman tool and hit the following URL to send an HTTP GET request to the controller method.

Once the request is successfully processed by the application and the HTTP 200 OK response is received, the message is published to the queue and can be verified from the below logs.

1
2
2020-07-27 22:24:03.566  INFO 8228 --- [nio-9091-exec-1] c.j.s.rabbitmq.controller.Publisher      : Sending message to the queue.
2020-07-27 22:24:03.577  INFO 8228 --- [nio-9091-exec-1] c.j.s.rabbitmq.controller.Publisher      : Message sent successfully to the queue, sending back the response to the user.

Once the message is successfully published, the method in the Subscriber.java will listen to the messages from the queue and can be verified from the below logs.

1
2
3
2020-07-27 22:13:46.116  INFO 1604 --- [ntContainer#0-1] c.j.s.rabbitmq.listen.Subscriber         : Listening messages from the queue!!
2020-07-27 22:13:46.117  INFO 1604 --- [ntContainer#0-1] c.j.s.rabbitmq.listen.Subscriber         : Received the following message from the queue= hello-world
2020-07-27 22:13:46.117  INFO 1604 --- [ntContainer#0-1] c.j.s.rabbitmq.listen.Subscriber         : Message received successfully from the queue.

That is all for this tutorial and I hope the article served you whatever you were looking for. Happy Learning and do not forget to share!

6. Summary

In this section, we learned:

  • Spring Boot and RabbitMQ
  • Steps to implement Hello World application with Spring Boot and RabbitMQ

You can download the sample application as an Eclipse project in the Downloads section.

7. Download the Eclipse Project

This was an example of Spring Boot and RabbitMQ.

Download
You can download the full source code of this example here: Spring Boot and RabbitMQ Hello World Example

Yatin

An experience full-stack engineer well versed with Core Java, Spring/Springboot, MVC, Security, AOP, Frontend (Angular & React), and cloud technologies (such as AWS, GCP, Jenkins, Docker, K8).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button