基于 SpringBoot + RabbitMQ 完成企业级应用通信

文章目录

  • [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 发送字符串

相关推荐
Java陈序员18 小时前
企业级!一个基于 Java 开发的开源 AI 应用开发平台!
spring boot·agent·mcp
杨运交1 天前
[041][公共模块]分布式唯一ID生成器设计与实现:一款灵活可扩展的雪花算法框架
spring boot
Flittly2 天前
【AgentScope Java新手村系列】(14)人机交互
java·spring boot·spring
Flynt3 天前
从Spring Boot 4.0升到4.1,我在Maven和gRPC上栽了跟头
java·spring boot·后端
掉鱼的猫4 天前
Spring Boot → Solon 注解迁移实战指南:一张对照表说清楚
java·spring boot
人活一口气5 天前
Spring Boot与AIGC的完美结合:从零搭建智能内容生成平台
java·spring boot·aigc
java小白小8 天前
SpringBoot(01): 初识SpringBoot,从Spring的痛点说起
spring boot
用户3169353811838 天前
如何从零编写一个 Spring Boot Starter
spring boot
程序员晓琪9 天前
约定大于配置:基于 Java 包名自动生成 API 版本路由的最佳实践
java·spring boot·后端
Flittly9 天前
【AgentScope Java新手村系列】(11)中断与恢复
java·spring boot·spring