關於RabbitMQ我就不過多介紹了,我得博客前面也有過說明,本篇博客主要介紹一下SpringBoot與RabbitMQ的整合
SpringBoot整合RabbitMQ,RabbitAutoConfiguration
爲我們SpringBoot整合RabbitMQ 的自動配置類
- 自動配置了連接工廠 ConnectionFactory
- RabbitProperties封裝了 RabbitMQ
- RabbitTemplate:給RabbitMQ發送和接受消息的
- AmqpAdmin:RabbitMQ的系統管理功能組件
我們的項目結構如下
配置文件
我們首先編寫配置文件連接RabbitMQ
spring.rabbitmq.host=localhost
spring.rabbitmq.password=guest
spring.rabbitmq.username=guest
spring.rabbitmq.port=5672
這樣我們的項目基本配置就OK了
RabbitAutoConfiguration會爲我們自動在容器中裝配RabbitTemplate
我們使用RabbitTemplate做一個消息生產與消費的Demo
@Test
public void send() {
Map<String,String> map = new HashMap<>();
map.put("firstName","yang");
map.put("lastName","zhao");
rabbitTemplate.convertAndSend("amq.direct","yz.zwl",map);
}
可以看到我們的消息已經存在隊列中了,接下來我們進行消費
@Test
public void receive() {
System.out.println(rabbitTemplate.receiveAndConvert("yz.zwl"));
}
可以看到我們已經成功消費了隊列中的消息
使用Json方式傳遞,並傳入對象Book
可以看到,我們的隊列中的消息並不是以JSON格式存儲的,所以我們需要進行配置自定義的消息轉化器
@Configuration
public class RabbitConfig {
@Bean
public MessageConverter messageConverter(){
return new Jackson2JsonMessageConverter();
}
}
接下來我們測試將對象作爲消息進行生產消費
@Test
public void send() {
rabbitTemplate.convertAndSend("amq.direct","yz.zwl",new Student("yz","男"));
}
可以看到我們的消息已經以JSON的格式存在隊列中
消費消息也完全OK
開啓基於註解的方式
RabbitAutoConfiguration同樣會爲我們自動在容器中裝配AmqpAdmin(創建和刪除 Exchange 、Queue、Bind,)
我們之前的Demo是我們在RabbitMQManagement系統中自己創建的Exchange、Queue、Bind。接下來我們使用代碼的方式進行創建
首先我們創建三種Exchange以及Queue
amqpAdmin.declareExchange(new DirectExchange("yzExchange.direct"));
amqpAdmin.declareExchange(new FanoutExchange("yzExchange.fanout"));
amqpAdmin.declareExchange(new TopicExchange("yzExchange.topic"));
amqpAdmin.declareQueue(new Queue("yz.zwl",true));
amqpAdmin.declareQueue(new Queue("zwl.yz",true));
amqpAdmin.declareQueue(new Queue("yz.news",true));
amqpAdmin.declareQueue(new Queue("yz.china",true));
amqpAdmin.declareQueue(new Queue("zwl.news",true));
我們可以使用RabbitListener註解消費消息,參數爲對應的隊列 進行監聽相關隊列
@Service
public class RabbitService {
@RabbitListener(queues = "yz.zwl")
public void receiveDirect(Student student){
System.out.println("yz.zwl消費消息");
System.out.println(student);
}
@RabbitListener(queues = "zwl.yz")
public void receiveDirect1(Student student){
System.out.println("zwl.yz消費消息");
System.out.println(student);
}
@RabbitListener(queues = "yz.news")
public void receiveDirect2(Student student){
System.out.println("yz.news消費消息");
System.out.println(student);
}
}
Direct Exchange
使用AmqpAdmin創建Bind
amqpAdmin.declareBinding(new Binding("yz.zwl",Binding.DestinationType.QUEUE,"yzExchange.direct","yz.zwl",null));
amqpAdmin.declareBinding(new Binding("zwl.yz",Binding.DestinationType.QUEUE,"yzExchange.direct","zwl.yz",null));
amqpAdmin.declareBinding(new Binding("yz.news",Binding.DestinationType.QUEUE,"yzExchange.direct","yz.news",null));
我們將Direct模式的**yzExchange.direct **綁定到yz.zwl、zwl.yz、yz.news
三個隊列,併爲他們三個聲明同名字的routing key
生產消息
rabbitTemplate.convertAndSend("yzExchange.direct","yz.zwl",new Student("yangzhao111","男"));
rabbitTemplate.convertAndSend("zwl.yz",new Student("yangzhao","男"));
可以看到只有對應的隊列消費了消息,證實了Direct 點對點的模式
Fanout Exchange
使用AmqpAdmin創建Bind
//fanout
amqpAdmin.declareBinding(new Binding("yz.zwl",Binding.DestinationType.QUEUE,"yzExchange.fanout","yz.zwl",null));
amqpAdmin.declareBinding(new Binding("zwl.yz",Binding.DestinationType.QUEUE,"yzExchange.fanout","zwl.yz",null));
amqpAdmin.declareBinding(new Binding("yz.news",Binding.DestinationType.QUEUE,"yzExchange.fanout","yz.news",null));
我們將Fanout模式的yzExchange.fanout綁定到yz.zwl、zwl.yz、yz.news
三個隊列,併爲他們三個聲明同名字的routing key
生產消息
rabbitTemplate.convertAndSend("yzExchange.fanout","yz.zwl",new Student("yangzhao","男"));
可以看到三個隊列都消費了消息,證實了Fanout的廣播效果,且與routing key無關
Topic Exchange
使用AmqpAdmin創建Bind
amqpAdmin.declareBinding(new Binding("zwl.yz",Binding.DestinationType.QUEUE,"yzExchange.topic","zwl.*",null));
amqpAdmin.declareBinding(new Binding("yz.zwl",Binding.DestinationType.QUEUE,"yzExchange.topic","*.zwl",null));
amqpAdmin.declareBinding(new Binding("yz.news",Binding.DestinationType.QUEUE,"yzExchange.topic","#.news",null));
我們將Topic模式的yzExchange.topic綁定到yz.zwl、zwl.yz、yz.news
三個隊列,併爲他們三個聲明對應的routing key *.zwl、zwl.*、#.news
生產消息
//topic
rabbitTemplate.convertAndSend("yzExchange.topic","yz.zwl",new Student("yangzhao","男"));
rabbitTemplate.convertAndSend("yzExchange.topic","zwl.news",new Student("yangzhao","男"));
因爲我們消息的routing key 與三個Binding的都匹配,所以三個隊列都消費了消息
Amqp刪除Exchange、Queue
amqpAdmin.deleteExchange("yzExchange.direct");
amqpAdmin.deleteExchange("yzExchange.fanout");
amqpAdmin.deleteExchange("yzExchange.topic");
amqpAdmin.deleteQueue("yz.zwl");
amqpAdmin.deleteQueue("zwl.yz");
amqpAdmin.deleteQueue("yz.news");
amqpAdmin.deleteQueue("yz.china");
amqpAdmin.deleteQueue("zwl.news");