SpringBoot+RabbitMQ完成应用通信

 更新时间:2025年06月12日 08:35:11   作者:新绿MEHO  
本文主要介绍了SpringBoot+RabbitMQ完成应用通信,通过订单系统发送订单消息并通知物流系统消费,解决了对象类型消息的序列化问题,感兴趣的可以了解一下

应用通信

作为⼀个消息队列, RabbitMQ也可以⽤作应⽤程序之间的通信. 上述代码⽣产者和消费者代码放在不同的应⽤中即可完成不同应⽤程序的通信.
接下来我们来看, 基于SpringBoot+RabbitMQ完成应⽤间的通信.

需求描述

⽤⼾下单成功之后, 通知物流系统, 进⾏发货。

订单系统作为⼀个⽣产者, 物流系统作为⼀个消费者。

创建项目

创建空项目

创建Module(order-service)

添加依赖

创建Module(logistics-service)

添加依赖

消息类型为字符串

编写订单代码

添加配置

spring:
  application:
    name: order-service
  rabbitmq:
    addresses: amqp://study:study@47.98.109.138:5672/order

声明队列

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();
    }
}

生产订单

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.Random;
import java.util.UUID;

@RequestMapping("/order")
@RestController
public class OrderController {
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @RequestMapping("create")
    public String create(){
        String orderId= UUID.randomUUID().toString();
        rabbitTemplate.convertAndSend("","order.create","订单信息,订单ID:"+orderId);
        return "下单成功";
    }
}

编写物流代码

添加配置

spring:
  application:
    name: logistics-service
  rabbitmq:
    addresses: amqp://study:study@47.98.109.138:5672/order
server:
  port: 9090

声明队列

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("order.create")
    public Queue createOrder() {
        return QueueBuilder.durable("order.create").build();
    }
}

消费订单

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);
    }
}

生产订单

消费订单

可以看到,订单已经被成功消费了,结果符合预期。 

消息类型为对象

下面的代码是以上面代码的基础,并进行增添删除编写而成的。

新增Module

因为订单系统和物流系统在生产和消费对象类型的消息时,会用到同一个结构体,为了便于代码编写,新增Module,把OrderInfo放到新增的Module中。

import lombok.Data;


@Data
public class OrderInfo{
    private String orderId;
    private String name;
}

编写订单代码

在order-service项目的OrderController中添加如下代码:

    @RequestMapping("create2")
    public String create2(){
        OrderInfo orderInfo=new OrderInfo();
        orderInfo.setOrderId(UUID.randomUUID().toString());
        orderInfo.setName("商品"+new Random().nextInt(100));
        rabbitTemplate.convertAndSend("","order.create",orderInfo);
        return "下单成功";
    }

生产对象类型订单消息

此时我们发现抛异常了,异常信息为SimpleMessageConverter只支持String, byte[] and Serializable类型的payloads,但是接收到的是order.model.OrderInfo对象。

解决办法1(实现序列化接口)

修改order-service下的OrderInfo类

import lombok.Data;

import java.io.Serializable;

@Data
public class OrderInfo implements Serializable {
    private String orderId;
    private String name;
}

虽然成功生成了对象类型的订单消息,但是我们看到消息的Payload并不直观,下面我们将采用两一种解决办法。

解决办法2(设置消息转换类型)

修改order-service中的OrderInfo

import lombok.Data;

@Data
public class OrderInfo{
    private String orderId;
    private String name;
}

查看RabbitTemplated的setMessageConverter方法,查看MessageConverter接口的实现类,我们将使用Jackson2JsonMessageConverter。

修改order-service中的RabbitMQConfig

import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
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();
    }

    @Bean
    public Jackson2JsonMessageConverter jsonMessageConverter(){
        return new Jackson2JsonMessageConverter();
    }
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory factory, Jackson2JsonMessageConverter jsonMessageConverter){
        RabbitTemplate rabbitTemplate = new RabbitTemplate(factory);
        rabbitTemplate.setMessageConverter(jsonMessageConverter);
        return rabbitTemplate;
    }
}

再次生产对象类型订单消息

此时再次查看队列中的消息,我们可以看到消息的Payload是非常直观的!!!

编写物流代码

修改logistics-service中的代码

import logistics.model.OrderInfo;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
@RabbitListener(queues = "order.create")
public class OrderListener {
    public void handMessage(String orderInfo) {
        System.out.println("接收到订单消息"+orderInfo);
    }

    public void handMessage(OrderInfo orderInfo) {
        System.out.println("接收到订单消息"+orderInfo);
    }
}

消费对象类型订单消息

但是过了许久,我们也没有看到队列中的消息被消费!!!

解决办法

原因是因为@RabbitListener(queues = "order.create")注解声明在类上面时,须结合@RabbitHandler注解来使用!!!

修改logistics-service中的代码

import logistics.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("接收到订单消息"+orderInfo);
    }

    @RabbitHandler
    public void handMessage(OrderInfo orderInfo) {
        System.out.println("接收到订单消息"+orderInfo);
    }
}

此时消费消息,但是发现又抛异常了

原因是因为,我们的确是针对生产对象类型消息的一方设置了MessageConverter,但是我们没有给消费对象类型消息的一方设置MessageConverter,导致消费对象类型消息的一方没有办法正确解析出消息。

解决办法,依旧是添加MessageConverter!!!

修改logistics-service中的RabbitMQConfig

import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
public class RabbitMQConfig {
    @Bean("order.create")
    public Queue createOrder() {
        return QueueBuilder.durable("order.create").build();
    }

    @Bean
    public Jackson2JsonMessageConverter jsonMessageConverter(){
        return new Jackson2JsonMessageConverter();
    }
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory factory, Jackson2JsonMessageConverter jsonMessageConverter){
        RabbitTemplate rabbitTemplate = new RabbitTemplate(factory);
        rabbitTemplate.setMessageConverter(jsonMessageConverter);
        return rabbitTemplate;
    }
}

再次消费消息 

此时我们可以看到,对象类型的订单消息可以正常消费了,符合预期。

到此这篇关于SpringBoot+RabbitMQ完成应用通信的文章就介绍到这了,更多相关SpringBoot RabbitMQ通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot统一返回结果问题

    SpringBoot统一返回结果问题

    这篇文章主要介绍了SpringBoot统一返回结果问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Java并发编程之详解ConcurrentHashMap类

    Java并发编程之详解ConcurrentHashMap类

    在之前的文章中已经为大家介绍了java并发编程的工具:BlockingQueue接口、ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue、BlockingDeque接口,本文为系列文章第八篇.需要的朋友可以参考下
    2021-06-06
  • Java中输入输出方式详细讲解

    Java中输入输出方式详细讲解

    这篇文章主要给大家介绍了关于Java中输入输出方式的相关资料,Java输入输出是指使用java提供的一些类和方法来实现数据的输入和输出,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-09-09
  • java 实现读取txt文本数据并以数组形式一行一行取值

    java 实现读取txt文本数据并以数组形式一行一行取值

    今天小编就为大家分享一篇java 实现读取txt文本数据并以数组形式一行一行取值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • Java实现登录密码强度校验的项目实践

    Java实现登录密码强度校验的项目实践

    本文主要介绍了Java实现登录密码强度校验的项目实践,包括使用正则表达式匹配校验和密码强度校验工具类这两种方法,具有一定的参考价值,感兴趣的可以了解一下
    2024-01-01
  • Java 生成透明图片的设置实现demo

    Java 生成透明图片的设置实现demo

    这篇文章主要为大家介绍了Java 生成透明图片的设置实现demo,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • vscode快速引入第三方jar包发QQ邮件

    vscode快速引入第三方jar包发QQ邮件

    这篇文章主要介绍了vscode快速引入第三方jar包发QQ邮件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Java中List<T>和List<?>的区别详解

    Java中List<T>和List<?>的区别详解

    这篇文章主要介绍了Java中List<T>和List<?>的区别详解。文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • springMVC之HandlerExceptionResolver使用

    springMVC之HandlerExceptionResolver使用

    这篇文章主要介绍了springMVC之HandlerExceptionResolver使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • 教你怎么用Java操作Redis

    教你怎么用Java操作Redis

    今天带大家来学习怎么用Java操作Redis,文中有非常详细的介绍,对正在学习java的小伙伴们有很好的帮助,建议有redis基础并熟悉redis的基本数据类型命令的小伙伴学习,需要的朋友可以参考下
    2021-05-05

最新评论