文章目录
- [1. 需求描述](#1. 需求描述)
- [2. 创建项目](#2. 创建项目)
- [3. 订单系统(生产者)](#3. 订单系统(生产者))
-
- [3.1 完善配置信息](#3.1 完善配置信息)
- [3.2 声明队列](#3.2 声明队列)
- [3.3 定义接口](#3.3 定义接口)
- [3.4 运行程序](#3.4 运行程序)
- [4. 物流系统(消费者)](#4. 物流系统(消费者))
-
- [4.1 完善配置信息](#4.1 完善配置信息)
- [4.2 监听队列](#4.2 监听队列)
- [4.3 运行程序](#4.3 运行程序)
- [5. 发送消息格式为对象](#5. 发送消息格式为对象)
1. 需求描述
作为一个消息队列,RabbitMQ 也可以用作应用程序之间的通信。把生产者和消费者代码放在不同的应用中,即可完成不同应用程序的通信。
接下来我们来看,基于 SpringBoot + RabbitMQ 完成应用间的通信。
需求描述:用户下单成功之后,通知物流系统,进行发货。(只讲具体功能实现)

订单系统作为一个生产者,物流系统作为一个消费者。
2. 创建项目
创建一个空的项目 rabbitmq-communication(其实就是一个空的文件夹)

在这个项目里,创建 Module(需要创建两个模块:订单系统和物流系统)

先新建一个订单模块

然后添加依赖,点击创建即可。

同样,按照上述方式,创建物流模块

然后添加依赖,点击创建即可。

最终结构如下

3. 订单系统(生产者)
3.1 完善配置信息
编辑 application.properties 文件,添加下面的内容:
yml
spring.rabbitmq.addresses=amqp://edison:edison@IP:5672/order
3.2 声明队列
代码如下所示:
java
package com.edison.order.config;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
@Bean("orderQueue")
public Queue orderQueue() {
return QueueBuilder.durable("order.create").build();
}
}
3.3 定义接口
编写下单接口,下单成功之后,发送订单消息
java
package com.edison.order.controller;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
@RequestMapping("/order")
@RestController
public class OrderController {
@Autowired
private RabbitTemplate rabbitTemplate; // 把rabbitmq的客户端注入进来
@RequestMapping("/create")
public String create() {
// 下单相关操作, ⽐如参数校验, 操作数据库等. 代码省略
// 发送消息通知
String orderId = UUID.randomUUID().toString();
rabbitTemplate.convertAndSend("", "order.create", "下单成功, 订单ID: "+orderId);
return "下单成功";
}
}
3.4 运行程序
启动服务,观察结果。
访问接口 http://127.0.0.1:8080/order/create 模拟下单请求,可以观察到消息发送成功

查看消息

4. 物流系统(消费者)
4.1 完善配置信息
8080 端口已经被订单系统占用了,修改物流系统的端口号为 9090'
java
server.port=9090
spring.rabbitmq.addresses=amqp://edison:edison@IP:5672/order
4.2 监听队列
代码如下所示:
java
package com.edison.logistics.listener;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class OrderListener {
// 指定监听队列的名称
@RabbitListener(queues = "order.create")
public void handMessage(String orderInfo) {
System.out.println("接收到订单消息: " + orderInfo);
// 收到消息后的处理, 代码省略
}
}
4.3 运行程序
启动服务,观察结果
访问订单系统的接口 http://127.0.0.1:8080/order/create 模拟下单请求。
在物流系统的日志中,可以观察到,通过 RabbitMQ,成功把下单信息传递给了物流系统。

5. 发送消息格式为对象
如果通过 RabbitTemplate 发送一个对象作为消息,我们需要对该对象进行序列化。
Spring AMQP 推荐使用 JSON 序列化,Spring AMQP 提供了 MessageConverter 等转换器,我们需要把一个 MessageConverter 设置到 RabbitTemplate 中。
代码如下所示:
java
@Bean
public MessageConverter messageConverter() {
return new JacksonJsonMessageConverter();
}
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, MessageConverter messageConverter) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(messageConverter); // 设置消息转换器
return rabbitTemplate;
}
定义对象
代码如下所示
java
package com.edison.order.model;
import lombok.Data;
@Data
public class OrderInfo {
private String orderId;
private String name;
private String price;
}
生产者代码
在 OrderController 中新增代码:
java
@RequestMapping("/create2")
public String create2() {
// 下单相关操作, ⽐如参数校验, 操作数据库等. 代码省略
// 发送消息通知
OrderInfo orderInfo = new OrderInfo();
orderInfo.setOrderId(UUID.randomUUID().toString());
orderInfo.setName("商品"+new Random().nextInt(100)); // 生成100以内的随机数
orderInfo.setPrice(ThreadLocalRandom.current().nextLong(1, 51)+"元");
rabbitTemplate.convertAndSend("", "order.create", orderInfo);
return "下单成功";
}
运行程序,可以从队列中拿到消息

消费者代码
首先,消费者也必须配置 MessageConverter
java
package com.edison.logistics.config;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.JacksonJsonMessageConverter;
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 messageConverter() {
return new JacksonJsonMessageConverter();
}
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, MessageConverter messageConverter) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(messageConverter); // 设置消息转换器
return rabbitTemplate;
}
}
然后进行处理
java
package com.edison.logistics.listener;
import com.edison.order.model.OrderInfo;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
@RabbitListener(queues = "order.create")
public class OrderListener {
// 指定监听队列的名称
@RabbitHandler
public void handMessage(String orderInfo) {
System.out.println("接收到订单消息String: " + orderInfo);
// 收到消息后的处理, 代码省略
}
// 指定监听队列的名称
@RabbitHandler
public void handMessage(OrderInfo orderInfo) {
System.out.println("接收到订单消息orderInfo: " + orderInfo);
// 收到消息后的处理, 代码省略
}
}
其中:
- @RabbitListener(queues = "order.create") 可以加在类上,也可以加在方法上,用于定义一个类或者方法作为消息的监听器。
- @RabbitHandler 是一个方法级别的注解,当使用 @RabbitHandler 注解时,这个方法将被调用处理特定的消息。
运行程序
启动服务,观察结果
访问订单系统的接口 http://127.0.0.1:8080/order/create2 模拟下单请求,发送对象
在物流系统的日志中,可以观察到,通过 RabbitMQ,成功把下单信息传递给了物流系统。

同样,还可以访问接口 http://127.0.0.1:8080/order/create 发送字符串
