【RabbitMQ】使用SpringAMQP的Publish/Subscribe(发布/订阅)

embedded/2024/10/21 19:28:09/

Publish/Subscribe

**发布(Publish)、订阅(Subscribe):**允许将同一个消息发送给多个消费者

在这里插入图片描述

**注意:**exchange负责消息路由,而不是存储,路由失败则消息丢失

常见的**X(exchange–交换机)***类型:

  • Fanout 广播
  • Direct 路由
  • Topoc 话题

发布订阅–FanoutExchange

案例三:利用SpringAMQP演示广播交换机的使用

1.在消费者(consumer包)中,创建一个FanoutConfig类,声明队列、交换机,并将两者绑定
@Configuration
public class FanoutConfig {//声明FanoutExchange交换机itcast.fanout@Beanpublic FanoutExchange fanoutExchange(){return new FanoutExchange("itcast.fanout");}//声明fanout.queue1队列@Beanpublic Queue fanoutQueue1(){return new Queue("fanout.queue1");}//绑定fanout.queue1队列和交换机@Beanpublic Binding bindingQueue1(Queue fanoutQueue1, FanoutExchange fanoutExchange){return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange);}//声明fanout.queue2队列@Beanpublic Queue fanoutQueue2(){return new Queue("fanout.queue2");}//绑定fanout.queue2队列和交换机@Beanpublic Binding bindingQueue2(Queue fanoutQueue2, FanoutExchange fanoutExchange){return BindingBuilder.bind(fanoutQueue2).to(fanoutExchange);}
}
2.在消费者(consumer包)中,编写两个消费者SpringRabbitListener方法,分别监听fanout.queue1和fanout.queue2
@Component
public class SpringRabbitListener {@RabbitListener(queues = "fanout.queue1")public void listenFanoutQueue1(String msg) {System.out.println("消费者接收到fanout.queue1的消息:【" + msg + "】");}@RabbitListener(queues = "fanout.queue2")public void listenFanoutQueue2(String msg) {System.out.println("消费者接收到fanout.queue2的消息:【" + msg + "】");}}
3.在publiSher中编写测试方法,向itcast.fanout发送消息
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringAmqpTest {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testpublic void testSendFanoutExchange() {// 交换机名称String exchangeName = "itcast.fanout";// 消息String message = "hello, every one!";// 发送消息rabbitTemplate.convertAndSend(exchangeName, "", message);}
}
4.运行,结果

在这里插入图片描述

发布订阅–DirectExchange

将接收到的消息根据规则路由到指定的Queue,因此称为路由模式(routes)

  • 每一个Queue都与Exchange设置一个BindingKey(暗号)
  • 发布者发送消息时,指定消息的RoutingKey
  • Exchange将消息路由到BindingKey与消息RoutingKey一致的队列

在这里插入图片描述

案例四:利用SpringAMQP演示DirectExchange的使用

1.直接用注解
@RabbitListener声明Exchange、Queue、RoutingKey
@QueueBinding注解用于绑定队列和交换器,并指定路由键
@Component
public class SpringRabbitListener {@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "direct.queue1"),exchange = @Exchange(name = "itcast.direct", type = ExchangeTypes.DIRECT),key = {"red", "blue"}))public void listenDirectQueue1(String msg){System.out.println("消费者接收到direct.queue1的消息:【" + msg + "】");}@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "direct.queue2"),exchange = @Exchange(name = "itcast.direct", type = ExchangeTypes.DIRECT),key = {"red", "yellow"}))public void listenDirectQueue2(String msg){System.out.println("消费者接收到direct.queue2的消息:【" + msg + "】");}}

在这里插入图片描述

2.测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringAmqpTest {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testpublic void testSendDirectExchange() {// 交换机名称String exchangeName = "itcast.direct";// 消息String message = "hello, red!";// 发送消息rabbitTemplate.convertAndSend(exchangeName, "red", message);}
}
3.结果

在这里插入图片描述

发布订阅–TopicExchange

TopicExchange与DirectExchange类似,区别在于routingKey必须是多个单词的列表,并且以**.**分割

Queue与Exchange指定BindingKey时可以使用通配符

  • # : 代指0个或多个单词
  • * : 代指一个单词

在这里插入图片描述

案例五:利用SpringAMQP演示TopicExchange的使用

1.直接用注解
@RabbitListener声明Exchange、Queue、RoutingKey
@QueueBinding注解用于绑定队列和交换器,并指定路由键
@Component
public class SpringRabbitListener {@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "topic.queue1"),exchange = @Exchange(name = "itcast.topic", type = ExchangeTypes.TOPIC),key = "china.#"))public void listenTopicQueue1(String msg){System.out.println("消费者接收到topic.queue1的消息:【" + msg + "】");}@RabbitListener(bindings = @QueueBinding(value = @Queue(name = "topic.queue2"),exchange = @Exchange(name = "itcast.topic", type = ExchangeTypes.TOPIC),key = "#.news"))public void listenTopicQueue2(String msg){System.out.println("消费者接收到topic.queue2的消息:【" + msg + "】");}
}

在这里插入图片描述

2.测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringAmqpTest {@Autowiredprivate RabbitTemplate rabbitTemplate;@Testpublic void testSendTopicExchange() {// 交换机名称String exchangeName = "itcast.topic";// 消息String message = "合理小姐是凑巧先生独一无二的女主角";//String message = "今天天气不错,我的心情好极了!";// 发送消息rabbitTemplate.convertAndSend(exchangeName, "china.news", message);//rabbitTemplate.convertAndSend(exchangeName, "china.weather", message);}}
3.结果

在这里插入图片描述


http://www.ppmy.cn/embedded/43147.html

相关文章

【Java面试】五、MySQL篇(下)

文章目录 1、事务的特性2、并发事务问题3、事务的隔离级别4、undo log 和 redo log4.1 底层结构4.2 redo log4.3 undo log 5、MVCC5.1 隐式字段5.2 undo log 版本链5.3 ReadView5.4 ReadView的匹配规则实现事务隔离 6、MySQL的主从同步原理7、分库分表7.1 垂直分库7.2 垂直分表…

C# 跨线程访问UI组件,serialPort1串口接收数据

在Windows应用程序(例如WinForms或WPF)中,UI组件(如按钮、文本框等)都在主线程(也称为UI线程)上运行。当你在一个非UI线程(例如,一个后台线程或者网络请求线程&#xff0…

Leetcode - 398周赛

目录 一,3151. 特殊数组 I 二,3152. 特殊数组 II 三,3153. 所有数对中数位不同之和 四,3154. 到达第 K 级台阶的方案数 一,3151. 特殊数组 I 本题就是判断一个数组是否是奇偶相间的,如果是,…

Java中的封装、继承和多态性详解

一、封装 技术难点 封装是面向对象编程的四大基本特性之一,它的主要目标是隐藏对象的内部状态和信息,只对外提供有限的访问接口。技术难点在于如何合理地设计类的私有成员变量和公有方法,以确保数据的安全性和操作的便捷性。封装要求开发者…

webserver服务器从零搭建到上线(六)|Timestamp类和InetAddress类

本节我们重点来谈论: 时间类和我们的初始化链接地址类 文章目录 Timestamp类成员函数实现 InetAddress类具体实现 Timestamp类 我们为什么要封装一个时间类呢? 这也是一个大型项目必须的基础组建,这样我们不仅可以提高代码的可读性&#xf…

Scala 入门介绍和环境搭建

一、简介 Scala 是一门以 Java 虚拟机(JVM)为运行环境并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言 (静态语言需要提前编译,如:Java、c、c 等,动态语言如:js)Scala 是一门多范式的编程…

WEB--NeDB

1.定义 NeDB is a lightweight document DBMS written in JavaScript. 全称:Node.js Embedded Database can be used both as embedded嵌入式(保存) and in-memory 内存式(不保存) It is a lightweight NoSQL data…

php爬虫之获取淘宝商品数据

爬取淘宝信息数据 首先需要先导入webdriver 1.from selenium import webdriver webdriver支持主流的浏览器,比如说:谷歌浏览器、火狐浏览器、IE浏览器等等 然后可以创建一个webdriver对象,通过这个对象就可以通过get方法请求网站 1.driver…