In this tutorial, we will explore the use of Spring AMQP to communicate with the RabbitMQ messaging middleware. All the previous article code examples are based on the RabbitMQ-Java-Client library. Spring AMQP also makes use of the same library, however, it provides a practical oriented approach to communicate with RabbitMQ. If you are already familiar with Spring stack, then you should use Spring AMQP for messaging with RabbitMQ.

If you are new to AMQP and RabbitMQ, please check out the Complete RabbitMQ tutorial from the beginning.

Prerequisites

What is Spring AMQP?

First of all, we need to understand why we need to use Spring AMQP and what extra features this library offers.

  • Just like other Spring projects, Spring AMQP applies the spring core dependency injection to the AMQP-based messaging application programming.
  • It also provides RabbitTemplate (class) and AmqpTemplate (interface) to send and receive messages easily.
  • Similarly, it has AmqpAdmin (interface) and RabbitAdmin (class) to declare/delete Queues, Exchanges, and Bindings.

Code examples with Spring AMQP

I am using Spring AMQP with Spring Boot and Spring MVC. Spring Boot is the standard way to use Spring Framework as it saves a lot of time figuring out the configurations. So the first thing is to add the necessary dependencies in your pom.xml.

We will create a Fanout Exchange with the namefanout.ex, a Queue as queue.ex, and bind them using an empty route.

1. Generate a Spring boot project

I recommend you to generate the project from start.spring.io and import it into your IDE (IntelliJ or Eclipse). I have already selected the Spring-web and Spring AMQP, all you need is download and import. I would like you to take a look at the dependencies added in pom.xml.

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

The other dependencies are for Spring MVC and testing.

2. Add the RabbitMQ related configurations

Step-1
First thing is to add the RabbitMQ Server related configuration. Add the following in your application.properties.

spring.rabbitmq.host= 127.0.0.1
spring.rabbitmq.port= 5672
spring.rabbitmq.username= guest
spring.rabbitmq.password= guest

Step-2
Create a package com.jbd.ampqlearning.fanout and a class SpringRabbitConfigs inside it. Now add the code to create a FanoutExchange (fanout.ex), a Queue (queue.ex) and bind the Queue with this fanout exchange.

package com.jbd.ampqlearning.fanout;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.Exchange;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringRabbitConfigs {
  private static final String EXCHANGE_NAME = "fanout.ex";
  private static final String QUEUE_NAME = "queue.ex";

  @Bean
  public Queue createQueue() {
    //For learning purpose - durable=false,
    // in a real project you may need to set this as true.
    return new Queue(QUEUE_NAME, true);
  }

  @Bean
  public Exchange fanoutExchange() {
    // durable=true, autoDelete=false
    return new FanoutExchange(EXCHANGE_NAME, true, false);
  }

  @Bean
  public Binding queueBinding() {
    return new Binding(QUEUE_NAME, Binding.DestinationType.QUEUE, EXCHANGE_NAME, "", null);
  }
}

NOTE: Spring boot manages the Connection, Channel and ConnectionFactory for you.

If you want to have more control over the ConnectionFactory, the below code is an example of the same. I don’t advise you to customize unless you need to.

@Configuration
public class SpringRabbitConfigs {
...  

  @Bean
  public ConnectionFactory connectionFactory() {
    CachingConnectionFactory connectionFactory = new CachingConnectionFactory("localhost");
    connectionFactory.setUsername("guest");
    connectionFactory.setPassword("guest");
    return connectionFactory;
  }
}

3. Create a message listener using @RabbitListener annotation

The @RabbitListener is a special annotation that makes a method as the message consumer/subscriber of any Queue in Spring AMQP. So create a class as MessageListener and add the below code in it.

package com.jbd.ampqlearning.fanout;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

@Service
public class MessageListener {

  /**
   * Assigns a Consumer to receive the messages whenever there is one.
   * @param message
   */
  @RabbitListener(queues = "queue.ex")
  public void receiveMessage(String message) {
    System.out.println("Received Message:" + message);
    System.out.println();
  }
}

4. Send a message using AmqpTemplate or RabbitTemplate

The AmqpTemplate is an interface and RabbitTemplateis the implementation class in Spring AMQP. I advise you to use the AmqpTemplate, however you may find a lot of examples on the internet directly making use of the RabbitTemplate.

The Spring AmqpTemplate is the high-level abstraction interface that you need to use to Send/Receive messages in your application. We will create a rest-api, whenever the url /sendMessage is hit, the MessageController should send a message to the fanout.ex. The fanout exchange should forward the message to queue.ex and finally MessageListener:receiveMessage should receive the message. So lets create the MessageController class as below.

package com.jbd.ampqlearning.fanout;

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Spring controller exposes api for Home controller.
 */
@RestController
public class MessageController {

  private final AmqpTemplate amqpTemplate;

  @Autowired
  public MessageController(AmqpTemplate amqpTemplate) {
    this.amqpTemplate = amqpTemplate;
  }

  @GetMapping("/sendMessage")
  public String sendMessage() {
    amqpTemplate.convertAndSend("fanout.ex", "", "Sample message using amqp template");
    return "Message Sent";
  }
}

Run the example

Now run the application as a spring boot app by running the below command from the terminal.

mvn spring-boot:run

Once the app is up and running, hit the url localhost:8080/sendMessage from a browser or just CURL it.

curl localhost:8080/sendMessage

Output:

Received Message:Sample message using amqp template

Conclusion:

I have tried to give you an overview of Spring AMQP usage to send and receive a message in Spring with the help of Spring boot. The final code example can be downloaded from the GitHub repo.