Master RabbitMQ with Spring AMQP: Install, Configure, and Implement 5 Core Messaging Patterns
This tutorial walks you through installing RabbitMQ on Windows and Linux, configuring it, and using Spring AMQP to implement five fundamental messaging patterns—simple, work, publish/subscribe, routing, and wildcard—complete with code examples and test endpoints.
Introduction
RabbitMQ is one of the most popular open‑source message brokers, lightweight, easy to deploy, and supports multiple messaging protocols. It can be used in distributed systems to meet high‑availability and large‑scale requirements.
Related Concepts
We first introduce key RabbitMQ concepts using the routing pattern as an example.
Installation and Configuration
Windows Installation
Install Erlang from http://erlang.org/download/otp_win64_21.3.exe
Install RabbitMQ from https://dl.bintray.com/rabbitmq/all/rabbitmq-server/3.7.14/rabbitmq-server-3.7.14.exe
After installation, go to the sbin directory and enable the management plugin:
rabbitmq-plugins enable rabbitmq_managementLinux Installation
Pull the RabbitMQ Docker image: docker pull rabbitmq:3.7.15 Run the container exposing the default ports:
docker run -p 5672:5672 -p 15672:15672 --name rabbitmq \
-d rabbitmq:3.7.15Enter the container and enable the management plugin:
docker exec -it rabbitmq /bin/bash
rabbitmq-plugins enable rabbitmq_managementOpen the firewall for external access:
firewall-cmd --zone=public --add-port=15672/tcp --permanent
firewall-cmd --zone=public --add-port=5672/tcp --permanent
firewall-cmd --reloadAccess and Configuration
Open http://localhost:15672/ and log in with the default credentials guest/guest.
Create a new user mall/mall with administrator role.
Create a virtual host /mall and assign permissions to the mall user.
Five Messaging Patterns
These patterns form the foundation of RabbitMQ‑based applications. Below we implement them with Spring AMQP.
Simple Pattern
A single producer, a single consumer, and one queue.
Spring AMQP Implementation
Add Spring AMQP dependency to pom.xml.
Configure connection in application.yml:
spring:
rabbitmq:
host: localhost
port: 5672
virtual-host: /mall
username: mall
password: mall
publisher-confirms: true
publisher-returns: trueCreate queue simple.hello, a producer SimpleSender, and a consumer SimpleReceiver.
@Configuration
public class SimpleRabbitConfig {
@Bean
public Queue hello() { return new Queue("simple.hello"); }
@Bean
public SimpleSender simpleSender() { return new SimpleSender(); }
@Bean
public SimpleReceiver simpleReceiver() { return new SimpleReceiver(); }
}
public class SimpleSender {
@Autowired private RabbitTemplate template;
private static final String QUEUE = "simple.hello";
public void send() { template.convertAndSend(QUEUE, "Hello World!"); }
}
@RabbitListener(queues = "simple.hello")
public class SimpleReceiver {
@RabbitHandler
public void receive(String in) { /* log */ }
}Work Queue Pattern
Multiple consumers compete for messages from a single queue.
Spring AMQP Implementation
Create queue work.hello, a producer WorkSender, and two consumers WorkReceiver (instances 1 and 2).
@Configuration
public class WorkRabbitConfig {
@Bean public Queue workQueue() { return new Queue("work.hello"); }
@Bean public WorkSender workSender() { return new WorkSender(); }
@Bean public WorkReceiver workReceiver1() { return new WorkReceiver(1); }
@Bean public WorkReceiver workReceiver2() { return new WorkReceiver(2); }
}
public class WorkSender {
@Autowired private RabbitTemplate template;
private static final String QUEUE = "work.hello";
public void send(int index) { /* build message with varying dots */ }
}
@RabbitListener(queues = "work.hello")
public class WorkReceiver {
private final int instance;
public WorkReceiver(int i) { this.instance = i; }
@RabbitHandler
public void receive(String in) { /* simulate work based on dot count */ }
}Publish/Subscribe (Fanout) Pattern
Messages are broadcast to all bound queues.
Spring AMQP Implementation
Declare a FanoutExchange named exchange.fanout, two anonymous queues, and bind them.
@Configuration
public class FanoutRabbitConfig {
@Bean public FanoutExchange fanout() { return new FanoutExchange("exchange.fanout"); }
@Bean public Queue fanoutQueue1() { return new AnonymousQueue(); }
@Bean public Queue fanoutQueue2() { return new AnonymousQueue(); }
@Bean public Binding fanoutBinding1(FanoutExchange fanout, Queue fanoutQueue1) { return BindingBuilder.bind(fanoutQueue1).to(fanout); }
@Bean public Binding fanoutBinding2(FanoutExchange fanout, Queue fanoutQueue2) { return BindingBuilder.bind(fanoutQueue2).to(fanout); }
@Bean public FanoutSender fanoutSender() { return new FanoutSender(); }
@Bean public FanoutReceiver fanoutReceiver() { return new FanoutReceiver(); }
}
public class FanoutSender {
@Autowired private RabbitTemplate template;
private static final String EXCHANGE = "exchange.fanout";
public void send(int index) { /* build message with dots */ template.convertAndSend(EXCHANGE, "", message); }
}
@RabbitListener(queues = "#{fanoutQueue1.name}")
public class FanoutReceiver {
@RabbitHandler
public void receive1(String in) { /* process */ }
@RabbitListener(queues = "#{fanoutQueue2.name}")
public void receive2(String in) { /* process */ }
}Routing (Direct) Pattern
Messages are routed to queues based on a routing key.
Spring AMQP Implementation
Declare a DirectExchange named exchange.direct, two anonymous queues, and bind them with keys orange, black, green.
@Configuration
public class DirectRabbitConfig {
@Bean public DirectExchange direct() { return new DirectExchange("exchange.direct"); }
@Bean public Queue directQueue1() { return new AnonymousQueue(); }
@Bean public Queue directQueue2() { return new AnonymousQueue(); }
@Bean public Binding directBinding1a(DirectExchange direct, Queue directQueue1) { return BindingBuilder.bind(directQueue1).to(direct).with("orange"); }
@Bean public Binding directBinding1b(DirectExchange direct, Queue directQueue1) { return BindingBuilder.bind(directQueue1).to(direct).with("black"); }
@Bean public Binding directBinding2a(DirectExchange direct, Queue directQueue2) { return BindingBuilder.bind(directQueue2).to(direct).with("green"); }
@Bean public Binding directBinding2b(DirectExchange direct, Queue directQueue2) { return BindingBuilder.bind(directQueue2).to(direct).with("black"); }
@Bean public DirectSender directSender() { return new DirectSender(); }
@Bean public DirectReceiver directReceiver() { return new DirectReceiver(); }
}
public class DirectSender {
@Autowired private RabbitTemplate template;
private static final String EXCHANGE = "exchange.direct";
private final String[] keys = {"orange", "black", "green"};
public void send(int index) { String key = keys[index % keys.length]; template.convertAndSend(EXCHANGE, key, "Hello " + key + " " + (index+1)); }
}
@RabbitListener(queues = "#{directQueue1.name}")
public class DirectReceiver {
@RabbitHandler
public void receive1(String in) { /* process */ }
@RabbitListener(queues = "#{directQueue2.name}")
public void receive2(String in) { /* process */ }
}Wildcard (Topic) Pattern
Routing based on pattern matching with * and # wildcards.
Spring AMQP Implementation
Declare a TopicExchange named exchange.topic, two anonymous queues, and bind them with patterns *.orange.*, *.*.rabbit (queue 1) and lazy.# (queue 2).
@Configuration
public class TopicRabbitConfig {
@Bean public TopicExchange topic() { return new TopicExchange("exchange.topic"); }
@Bean public Queue topicQueue1() { return new AnonymousQueue(); }
@Bean public Queue topicQueue2() { return new AnonymousQueue(); }
@Bean public Binding topicBinding1a(TopicExchange topic, Queue topicQueue1) { return BindingBuilder.bind(topicQueue1).to(topic).with("*.orange.*"); }
@Bean public Binding topicBinding1b(TopicExchange topic, Queue topicQueue1) { return BindingBuilder.bind(topicQueue1).to(topic).with("*.*.rabbit"); }
@Bean public Binding topicBinding2a(TopicExchange topic, Queue topicQueue2) { return BindingBuilder.bind(topicQueue2).to(topic).with("lazy.#"); }
@Bean public TopicSender topicSender() { return new TopicSender(); }
@Bean public TopicReceiver topicReceiver() { return new TopicReceiver(); }
}
public class TopicSender {
@Autowired private RabbitTemplate template;
private static final String EXCHANGE = "exchange.topic";
private final String[] keys = {"quick.orange.rabbit", "lazy.orange.elephant", "quick.orange.fox", "lazy.brown.fox", "lazy.pink.rabbit", "quick.brown.fox"};
public void send(int index) { String key = keys[index % keys.length]; template.convertAndSend(EXCHANGE, key, "Hello " + key + " " + (index+1)); }
}
@RabbitListener(queues = "#{topicQueue1.name}")
public class TopicReceiver {
@RabbitHandler
public void receive1(String in) { /* process */ }
@RabbitListener(queues = "#{topicQueue2.name}")
public void receive2(String in) { /* process */ }
}Reference
RabbitMQ Tutorials: https://www.rabbitmq.com/getstarted.html
Source Code
https://github.com/macrozheng/mall-learning/tree/master/mall-tiny-rabbit
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
