[toc]
| 单词 | 词性 | 音标 | 含义 |
|---|---|---|---|
| starter | n. | /ˈstɑːtə(r)/ | 启动器(SpringBoot 场景依赖包) |
| template | n. | /ˈtemplɪt/ | 模板(RabbitTemplate,发送消息的对象) |
| listener | n. | /ˈlɪsənə(r)/ | 监听器(监听队列接收消息) |
| binding | n. | /ˈbaɪndɪŋ/ | 绑定(交换机和队列的对应关系) |
| quorum | n. | /ˈkwɔːrəm/ | 仲裁(Quorum 队列,4 生产推荐的高可用队列) |
| durable | adj. | /ˈdjʊərəbl/ | 持久化的(重启不丢失) |
Lecture03-RabbitMQ-SpringBoot整合
环境:Spring Boot 3.x +
spring-boot-starter-amqp+ RabbitMQ 4(Docker 方式,见《RabbitMQ4-Ubuntu22.04-安装与操作清单》) 目标:生产者发消息、消费者收消息;交换机 / 队列 / 绑定关系用两种方式实现 全程只讲用法。前置:RabbitMQ 4 已用 Docker 跑起来,管理台账号admin / admin123(第 3 步设的)。
1、前置:添加依赖 + 连接配置
① pom.xml 加依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.0.0</version> <!-- 以当前稳定 4.x 为准 -->
<relativePath/>
</parent>
<properties>
<java.version>17</java.version> <!-- SpringBoot4 基线 Java 17+ -->
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
② application.yml 配置连接
spring:
rabbitmq:
host: localhost # Docker 在本地则 localhost,远程服务器填 IP
port: 5672
username: admin # 第 3 步创建容器时设的用户
password: admin123
virtual-host: / # 默认虚拟主机
说明:连接参数和你
docker run设的RABBITMQ_DEFAULT_USER / PASS一致。连不上先查 host/port/账号。
2、交换机、队列、绑定的两种创建方式
目标:消息 发到交换机 → 按路由键 → 进入队列 → 被消费者取走。交换机、队列、绑定关系(exchange + routing key + queue)是整套前提。
1、方式一:手动在 Management UI 创建(SpringBoot 代码最简)
① 在 UI 上建好(参考《安装与操作清单》第 4 步)
- 交换机:
demo.exchange(type=direct,Durable) - 队列:
demo.queue(Durable) - 绑定:从
demo.exchange→demo.queue,Routing key =demo.routing
② SpringBoot 这边代码很简——不用声明任何 @Bean,因为交换机和队列已经在 UI 里建好了,代码只负责收发:
// 生产者
@RestController
public class ProducerController {
@Autowired
private RabbitTemplate rabbitTemplate;
@GetMapping("/send")
public String send() {
rabbitTemplate.convertAndSend("demo.exchange", "demo.routing", "Hello RabbitMQ 4 !");
return "已发送";
}
}
// 消费者
@Component
public class DemoConsumer {
@RabbitListener(queues = "demo.queue") // 只监听队列名,其余 UI 已建好
public void onMessage(String message) {
System.out.println("收到消息:" + message);
}
}
- 特点:代码最少;前提是队列 / 交换机已手动建好,否则启动时
@RabbitListener找不到队列会报错。
2、方式二:SpringBoot 配置 + 启动时自动创建
① 写一个配置类,用 @Bean 声明交换机、队列、绑定——SpringBoot 启动时会自动在 RabbitMQ 里创建(若不存在):
@Configuration
public class RabbitConfig {
public static final String EXCHANGE = "demo2.exchange";
public static final String QUEUE = "demo2.queue";
public static final String ROUTING = "demo2.routing";
// 交换机(direct,持久化)
@Bean
public DirectExchange exchange() {
return new DirectExchange(EXCHANGE, true, false);
}
// 队列(经典队列,持久化)
@Bean
public Queue queue() {
return QueueBuilder.durable(QUEUE).build();
// RabbitMQ 4 生产建议用 Quorum 队列(单节点即可测试,副本=1;集群才有复制/高可用):
// return QueueBuilder.durable(QUEUE).quorum().build();
}
// 绑定:queue 绑到 exchange,路由键 ROUTING
@Bean
public Binding binding() {
return BindingBuilder.bind(queue()).to(exchange()).with(ROUTING);
}
}
② 生产者和消费者代码不变(把队列名换成常量 QUEUE 即可):
@RabbitListener(queues = RabbitConfig.QUEUE) // 消费者
rabbitTemplate.convertAndSend(RabbitConfig.EXCHANGE, RabbitConfig.ROUTING, "Hello ...");
- 特点:配置即代码,启动自动建,无需手动 UI;缺点是结构写在代码里、改结构要改代码重启。
3、两种方式对比
| 维度 | 方式一:UI 手动创建 | 方式二:代码自动创建 |
|---|---|---|
| 交换机/队列来源 | Management UI 手动建 | SpringBoot 启动时 @Bean 自动建 |
| SpringBoot 代码 | 最简(只写收发) | 需 @Configuration 声明 3 个 @Bean |
| 结构谁说了算 | 运维手动维护 | 随代码走 |
| 适用场景 | 生产、结构固定 | 学习、开发期图省事 |
3、生产者发送消息
核心方法:RabbitTemplate.convertAndSend(交换机, 路由键, 消息)
// 字符串
rabbitTemplate.convertAndSend(EXCHANGE, ROUTING, "Hello RabbitMQ 4 !");
// 对象(自动序列化为 JSON)
rabbitTemplate.convertAndSend(EXCHANGE, ROUTING, new Order(1, "鲜花"));
// 什么都不传 = 发到默认交换机(按队列名直接路由)
rabbitTemplate.convertAndSend("demo.queue", "直接发到队列");
验证发送成功:
- 浏览器调
http://localhost:8080/send - 到 Management UI → Queues →
demo.queue→ Get messages 能看到消息;或看控制台消费者打印
关键点:发送时给的路由键必须和绑定时一致,否则消息进不了队列(发到交换机但路由不到任何队列,消息丢失)。
4、消费者接收消息
核心注解:@RabbitListener(queues = "队列名")
@Component
public class Consumer {
@RabbitListener(queues = "demo.queue")
public void onMessage(String message) {
System.out.println("收到:" + message);
}
}
5、验证流程 + 常见问题
跑通顺序
- RabbitMQ 容器已
Up(docker ps) - SpringBoot 启动无报错(方式二会自动建交换机/队列/绑定)
- 调
/send接口发消息 - 消费者控制台打印出消息,或 UI 队列里看到消息 ✅
常见问题速查
| 现象 | 可能原因 | 处理 |
|---|---|---|
| 连接失败 | host/port/账号不对 | 对照 yml 和 docker run 设的用户密码;guest 已被删,别用 guest |
| 启动报"队列不存在" | 方式一没在 UI 建队列 | 先到 UI 建 demo.queue;或改用方式二自动建 |
| 消息发不出去、队列没有 | 路由键和绑定不一致 | 检查发送的 ROUTING 与绑定的 routing key 是否一致 |
| 消费者收不到 | 监听队列名写错 | 核对 @RabbitListener(queues=...) 与实际队列名 |
| 想用 Quorum 队列 | 4 生产建议 | QueueBuilder.durable(QUEUE).quorum().build() |
6、本教程用到的核心类速查
| 东西 | 角色 |
|---|---|
RabbitTemplate.convertAndSend(交换机, 路由键, 消息) | 生产者发送 |
@RabbitListener(queues = "队列名") | 消费者监听 |
@Bean Queue / DirectExchange / Binding + BindingBuilder | 方式二:代码自动创建 |
spring-boot-starter-amqp | Spring 对 RabbitMQ 的封装依赖 |
7、本节验证
- 会加依赖并配置连接 ✅
- 会用两种方式创建交换机/队列/绑定(UI 手动 vs 代码自动)✅
- 会用 RabbitTemplate 发送消息 ✅
- 会用 @RabbitListener 接收消息并跑通验证 ✅