– Tutorial: “Spring Boot Rabbitmq Multiple Queues Example using RabbitMq Exchange to Exchange Topology – Spring Boot Rabbitmq Multiple Listeners”
In the post, I show you how to work with SpringBoot RabbitMq Exchange to Exchange Topology to develop an example “Rabbitmq Multiple Queues and Multiple Listeners”.
* Technologies:
– Java 8
– Maven
– Spring Tool Suite
– Spring Boot
– RabbitMq
RabbitMq Exchange to Exchange – Spring Boot Rabbitmq Multiple Queues Example
We create a RabbitMQ topology with 2 topic exchanges and 3 binding queues:

Scenarios with above design:
– when we send a message with routing key: sys.prod.info
, it will be delivered by path: X1 -> Q3.
– when we send a message with routing key: app.prod.error
, it will be delivered by path: X1 -> X2 -> {Q2, Q3}.
– when we send a message with routing key: sys.test.error
, it will be delivered by path: X1 -> X2 -> Q1.
Practices – Spring Boot Rabbitmq Multiple Queues Example
In the tutorial, we create 2 SpringBoot project as below:

– Step to do:
– Create SpringBoot projects
– Define data model
– Implement RabbitMq Producer
– Implement RabbitMq consumer
– Run and check results
Create SpringBoot projects
Using SpringToolSuite, create 2 SpringBoot projects, then add need dependency spring-boot-starter-amqp
:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
Define Spring Data Model – Spring Boot RabbitMQ Multiple Queues Example
Create Log data model for both projects:
package com.loizenjava.rabbitmq.model;
public class Log {
private String content;
private String routingKey;
public Log(){};
public Log(String content, String routingKey){
this.content = content;
this.routingKey = routingKey;
}
public String getContent(){
return this.content;
}
public void setContent(String content){
this.content = content;
}
public String getRoutingKey(){
return this.routingKey;
}
public void setRoutingKey(String routingKey){
this.routingKey = routingKey;
}
@Override
public String toString() {
return String.format("{content = %s, routingKey = %s}", content, routingKey);
}
}
Now it’s time for implementation. Let’s go!
Configure SpringBoot RabbitMq Producer – Spring Boot RabbitMQ Multiple Queues Example
package com.loizenjava.rabbitmq.config;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMqConfig {
@Bean
public MessageConverter jsonMessageConverter(){
return new Jackson2JsonMessageConverter();
}
public AmqpTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(jsonMessageConverter());
return rabbitTemplate;
}
}
Open application.properties, add configuration:
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
jsa.rabbitmq.exchange=jsa.exchange.logs
jsa.rabbitmq.queue=jsa.queue
jsa.rabbitmq.routingkey=jsa.routingkey
Implement SpringBoot RabbitMq Producer
package com.loizenjava.rabbitmq.producer;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import com.loizenjava.rabbitmq.model.Log;
@Component
public class Producer {
@Autowired
private AmqpTemplate amqpTemplate;
@Value("${jsa.rabbitmq.exchange}")
private String exchange;
public void produce(Log logs){
String routingKey = logs.getRoutingKey();
amqpTemplate.convertAndSend(exchange, routingKey, logs);
System.out.println("Send msg = " + logs);
}
}
Implement SpringBoot RabbitMQ Producer Client
package com.loizenjava.rabbitmq;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.loizenjava.rabbitmq.model.Log;
import com.loizenjava.rabbitmq.producer.Producer;
@SpringBootApplication
public class SpringRabbitMqProducerApplication implements CommandLineRunner{
public static void main(String[] args) {
SpringApplication.run(SpringRabbitMqProducerApplication.class, args);
}
@Autowired
Producer producer;
@Override
public void run(String... args) throws Exception {
/**
* 1
*/
String content = "2014-03-05 10:58:51.1 INFO 45469 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/7.0.52";
String routingKey = "sys.dev.info";
// send to RabbitMQ
producer.produce(new Log(content, routingKey));
/**
* 2
*/
content = "2017-10-10 10:57:51.10 ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]]";
routingKey = "sys.test.error";
// send to RabbitMQ
producer.produce(new Log(content, routingKey));
/**
* 3
*/
content = "2017-10-10 10:57:51.112 ERROR java.lang.Exception: java.lang.Exception";
routingKey = "app.prod.error";
// send to RabbitMQ
producer.produce(new Log(content, routingKey));
}
}
Configure SpringBoot RabbitMQ Consumer
package com.loizenjava.rabbitmq.config;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMqConfig {
@Bean
public MessageConverter jsonMessageConverter(){
return new Jackson2JsonMessageConverter();
}
@Bean
public SimpleRabbitListenerContainerFactory jsaFactory(ConnectionFactory connectionFactory,
SimpleRabbitListenerContainerFactoryConfigurer configurer) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
configurer.configure(factory, connectionFactory);
factory.setMessageConverter(jsonMessageConverter());
return factory;
}
}
Open application.properties, add configuration:
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
jsa.rabbitmq.queue=jsa.queue.logs.application-error
#jsa.rabbitmq.queue=jsa.queue.logs.system-error
#jsa.rabbitmq.queue=jsa.queue.logs.production
Implement SpringBoot RabbitMQ Consumer
package com.loizenjava.rabbitmq.consumer;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import com.loizenjava.rabbitmq.model.Log;
@Component
public class Consumer {
@RabbitListener(queues="${jsa.rabbitmq.queue}", containerFactory="jsaFactory")
public void recievedMessage(Log logs) {
System.out.println("Recieved Message: " + logs);
}
}
Run and Check Results
– Setup RabbitMq exchange, queues:
Enable rabbitmq_management by cmd: rabbitmq-plugins enable rabbitmq_management --online
. Then go to: http://localhost:15672
-> login with user/password: guest
/guest
.
– Add RabbitMQ exchanges:
Go to http://localhost:15672/#/exchanges
, add 2 exchanges: {jsa.exchange.logs
, jsa.exchange.logs.error
}.

– Add RabbitMQ Queue:
Go to http://localhost:15672/#/queues
, add 3 queues: {jsa.queue.logs.application-error
, jsa.queue.logs.system-error
, jsa.queue.logs.production
}.

– Binding the queues & exchanges:


– Run SpringBoot-RabbitMQ-Producer with commandline mvn spring-boot:run
,
-> Console’s logs:
Send msg = {content = 2014-03-05 10:58:51.1 INFO 45469 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/7.0.52, routingKey = sys.prod.info}
Send msg = {content = 2017-10-10 10:57:51.10 ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]], routingKey = sys.test.error}
Send msg = {content = 2017-10-10 10:57:51.112 ERROR java.lang.Exception: java.lang.Exception, routingKey = app.prod.error}
– See queues’ status:

– Run SpringBoot-RabbitMQ-Consumer which listen to jsa.queue.logs.application-error
queue with configuration:
jsa.rabbitmq.queue=jsa.queue.logs.application-error
:
– Console’s logs:
Recieved Message: {content = 2017-10-10 10:57:51.112 ERROR java.lang.Exception: java.lang.Exception, routingKey = app.prod.error}
– Run SpringBoot-RabbitMQ-Consumer which listen to jsa.queue.logs.system-error
queue with configuration:
jsa.rabbitmq.queue=jsa.queue.logs.system-error
:
-> Console’s logs:
Recieved Message: {content = 2017-10-10 10:57:51.10 ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]], routingKey = sys.test.error}
– Run SpringBoot-RabbitMQ-Consumer which listen to jsa.queue.logs.production
queue with configuration:
jsa.rabbitmq.queue=jsa.queue.logs.production
:
– Console’s logs:
Recieved Message: {content = 2014-03-05 10:58:51.1 INFO 45469 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/7.0.52, routingKey = sys.prod.info}
Recieved Message: {content = 2017-10-10 10:57:51.112 ERROR java.lang.Exception: java.lang.Exception, routingKey = app.prod.error}
Read More
– Reference Link: RabbitMQ Exchange Topic
SourceCode
– SpringBoot-RabbitMQ-Producer
– SpringBoot-RabbitMQ-Consumer