SpringBoot——整合RabbitMQ收发消息

news2024/11/16 1:50:31

目录

RabbitMQ消息队列 

项目总结

新建一个SpringBoot项目

pom.xml

application.properties配置文件

index.html前端页面

RabbitMQConfig配置类

RabbitMQProducer生产者

RabbitMQConsumer消费者

IndexController控制器

SpringbootRabbitmqApplication启动类

 测试


RabbitMQ消息队列 

  • 消息中间件是位于两个或多个应用程序之间的中介软件,它允许应用程序相互通信和数据交换,而无需直接连接和交互。
  • RabbitMQ 作为消息中间件,提供了这种消息传递的机制和基础架构,使得不同系统之间能够通过异步消息队列进行有效通信。 
  • 它是一个基于AMQP(Advanced Message Queuing Protocol,高级消息队列协议)协议的消息代理,提供了跨应用和跨服务的异步通信能力。
  • RabbitMQ的核心概念包括:

    • 消息(Message):数据的最小单位,包含了消息头和消息体。
    • 队列(Queue):用于存储消息,等待被消费者接收和处理。
    • 交换器(Exchange):负责接收消息并将其路由到合适的队列,基于预定义的规则。
      • 直接交换(Direct Exchange):基于路由键的精确匹配。
      • 主题交换(Topic Exchange):基于路由键的模式匹配。
      • 扇形交换(Fanout Exchange):广播消息到所有绑定的队列。
      • 首选交换(Headers Exchange):基于消息头进行匹配。(headers交换机和direct交换机完全一致,但性能差很多,目前几乎用不到了)
    • 绑定(Binding):定义交换器与队列之间的关系,确定消息的路由规则。
    • 路由键(Routing Key):用于在交换器和队列之间路由消息。
    • 消费者(Consumer):从队列中接收和处理消息的应用程序或服务。
    • 发布者(Producer):向交换器发送消息的应用程序或服务。
  • RabbitMQ广泛用于构建分布式系统、微服务架构和事件驱动架构,以实现异步通信、负载分担、数据解耦和高可用性。

项目总结

  1. 添加依赖:在Spring Boot项目的pom.xml文件中添加RabbitMQ的依赖

  2. 配置RabbitMQ连接信息:在application.propertiesapplication.yml文件中配置RabbitMQ的连接信息,包括主机名、端口号、用户名、密码等信息。

  3. 创建配置类

    1. 使用@Bean注解定义Exchange和Queue,并绑定它们的关系,以确保消息能够被正确路由和传递。

    2. 使用@Bean注入CachingConnectionFactory缓存 连接工厂对象,用于开启RabbitMQ的消息发送确认模式

  4. 创建生产者:编写一个发送消息的生产者(Producer),可以是一个服务类或控制器方法。使用RabbitTemplate来发送消息到RabbitMQ的Exchange。

  5. 创建消费者:编写一个接收消息的消费者(Consumer),使用@RabbitListener监听指定的Queue,并处理接收到的消息,比如打印在控制台上。

  6. 启动项目和RabbitMQ服务后,项目的工作流程

    1. 打开浏览器访问页面,在文本域填写要发送信息,点击“发送”,

    2. 后端IndexController控制器接收到用户提交的消息后,由生产者将消息发送给RabbitMQ的交换机,RabbitMQ再将消息根据路由键路由到队列中,并且将结果反馈给服务器,服务器将打印”消息发送成功“的日志

    3. 消费者中监听此队列就会立刻收到并处理接收到的消息,打印到控制台上

自己从填写要发送的信息的地方开始分析,顺藤摸瓜,将项目的几个文件串连起来

新建一个SpringBoot项目

项目结构:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.12.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.study</groupId>
	<artifactId>springboot_rabbitmq</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springboot_rabbitmq</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>8</java.version>
	</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-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.amqp</groupId>
			<artifactId>spring-rabbit-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

application.properties配置文件

spring.rabbitmq.host=192.168.40.128
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=123456

# 指定队列,交换机,路由键的名称
#队列用于存储消息,生产者发送消息到队列,消费者从队列接收消息进行处理。
rabbit.queue.name=springboot.queue.test
#交换机负责将消息路由到一个或多个队列中,根据指定的路由键来确定消息的路由规则。
rabbit.exchange.name=springboot.exchange.test
#在消息发送时,会指定消息的路由键,交换机根据这个路由键来决定将消息路由到哪些队列中。
rabbit.routing.key=springboot.routingkey.test

index.html前端页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <!--发送后,会触发IndexController的sendMessage方法-->
    <form action="/sendMessage" method="post">
        <!--在文本域填写要发送的消息-->
        <textarea rows="4" cols="40" name="message"></textarea>
        <!--点击"发送"按钮-->
        <br><input type="submit" value="发送"/>
    </form>

</body>
</html>

RabbitMQConfig配置类

package com.study.springboot_rabbitmq.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置类: 绑定队列和交换器
 */
@Configuration
public class RabbitMQConfig {

    @Value("${rabbit.queue.name}")
    String queueName;

    @Value("${rabbit.exchange.name}")
    String exchangeName;

    @Value("${rabbit.routing.key}")
    String routingKey;

    @Bean()
    public Queue initQueue(){//创建队列
        return new Queue(queueName);
    }

    @Bean()
    public DirectExchange initDirectExchange(){//创建交换器
        return new DirectExchange(exchangeName);
    }

    @Bean
    public Binding bindingDirect(){//将队列与交换器绑定
        return BindingBuilder.bind(initQueue()).to(initDirectExchange()).with(routingKey);
    }
}

RabbitMQProducer生产者

package com.study.springboot_rabbitmq.service;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * 消息生产者
 */
@Service
public class RabbitMQProducer {

    @Autowired
    RabbitTemplate rabbitTemplate;

    //读取配置文件中的交换器名称和路由键名称
    @Value("${rabbit.exchange.name}")
    String exchangeName;

    @Value("${rabbit.routing.key}")
    String routingKey;

    //将消息发送给RabbitMQ的交换机,交换机通过路由键决定将消息路由到哪些队列
    public void send(String message){
        rabbitTemplate.convertAndSend(exchangeName,routingKey,message);
    }
}

RabbitMQConsumer消费者

package com.study.springboot_rabbitmq.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

/**
 * 消息消费者
 */
@Service
public class RabbitMQConsumer {

    private static final Logger log= LoggerFactory.getLogger(RabbitMQConsumer.class);

    //使用@RabbitListener监听配置文件中的队列,当收到消息后,将其打印在控制台上
    @RabbitListener(queues = "${rabbit.queue.name}")
    public void getMessage(String message){
        log.info("消费者收到消息:{}",message);
    }
}

IndexController控制器

  • 发送确认模式:在生产者向RabbitMQ发送消息后,RabbitMQ可以给生产者一个反馈消息,这个反馈消息中会包含接收是否成功、失败原因等一系列内容
package com.study.springboot_rabbitmq.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Caching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置类: 绑定队列和交换器
 */
@Configuration
public class RabbitMQConfig {

    private static final Logger log= LoggerFactory.getLogger(RabbitMQConfig.class);

    @Autowired
    private CachingConnectionFactory connectionFactory;

    @Value("${rabbit.queue.name}")
    String queueName;

    @Value("${rabbit.exchange.name}")
    String exchangeName;

    @Value("${rabbit.routing.key}")
    String routingKey;

    @Bean()
    public Queue initQueue(){//创建队列
        return new Queue(queueName);
    }

    @Bean()
    public DirectExchange initDirectExchange(){//创建交换器
        return new DirectExchange(exchangeName);
    }

    @Bean
    public Binding bindingDirect(){//将队列与交换器绑定
        return BindingBuilder.bind(initQueue()).to(initDirectExchange()).with(routingKey);
    }

    //RabbitMQ收到消息后,把结果反馈给服务器,服务器将打印日志
    @Bean
    public RabbitTemplate rabbitTemplate(){
        //消息发送成功后触发确认方法
        connectionFactory.setPublisherConfirmType(CachingConnectionFactory.ConfirmType.CORRELATED);
        //消息发送失败后触发回调方法
        connectionFactory.setPublisherReturns(true);
        //通过连接工厂对象创建RabbitTemplate对象
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        //若交换器无法匹配到指定队列,则取消发送消息
        rabbitTemplate.setMandatory(true);
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {//ack:RabbitMQ返回的应答
                if(ack){
                    log.info("消息发送成功");
                }else{
                    log.info("消息发送失败,原因: {}",cause);
                }
            }
        });
        rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            @Override
            public void returnedMessage(Message message, int i, String s, String s1, String s2) {
                log.info("消息发送失败: {}",message);

            }
        });
        return rabbitTemplate;
    }
}

SpringbootRabbitmqApplication启动类

package com.study.springboot_rabbitmq;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootRabbitmqApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringbootRabbitmqApplication.class, args);
	}

}

 测试

开启RabbitMQ服务,启动项目

从Spring Boot项目的角度来看,无论RabbitMQ运行在Windows还是Linux上,整合RabbitMQ的方式都是基本一致的,只要你的Spring Boot应用程序连接到RabbitMQ服务器,并使用RabbitMQ客户端库进行通信即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1705840.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS 介绍及用法,常用属性

一、CSS介绍 A. 简介 CSS全称&#xff1a;全称为层叠样式表&#xff08;Cascading Style Sheets&#xff09;&#xff0c;是一种用于描述网页外观和格式的计算机语言。CSS可以使网页的布局更加丰富和多样化&#xff0c;并且可以将样式信息与网页内容分离&#xff0c;使得网…

【JAVASE】接口(上)

一&#xff1a;接口的概念 在现实生活中&#xff0c;接口的例子比比皆是&#xff0c;比如&#xff1a;笔记本上上的USB接口。 电脑上的USB口上可以插:U盘、鼠标、键盘等。 电源插座插孔上可以插入&#xff1a;电脑、电视机等。 通过以上例子可以看出&#xff1a;接口就是公共…

0527_C++1

练习1&#xff1a; 定义自己的命名空间my_sapce&#xff0c;在my_sapce中定义string类型的变量s1&#xff0c;再定义一个函数完成对字符串的逆置。 #include <iostream>using namespace std; namespace my_space {string s1"hello world";void my_strreverse…

在银行申贷之前,是否需要查大数据信用报告呢?

在现代社会&#xff0c;信用是非常重要的经济资源&#xff0c;而信用报告则是评估个人信用状况的重要依据。在银行申贷过程中&#xff0c;通常需要提供个人的信用报告&#xff0c;以评估借款人的信用状况和还款能力。那么&#xff0c;在银行申贷之前&#xff0c;是否需要查大数…

深入学习 torch.distributions

0. 引言 前几天分几篇博文精细地讲述了《von Mises-Fisher 分布》, 以及相应的 PyTorch 实现《von Mises-Fisher Distribution (代码解析)》, 其中以 Uniform 分布为例简要介绍了 torch.distributions 包的用法. 本以为已经可以了, 但这两天看到论文 The Power Spherical dist…

ZYNQ AXI4 FDMA内存读写

1 概述 如果用过ZYNQ的都知道,要直接操作PS的DDR 通常是DMA 或者VDMA,然而用过XILINX 的DMA IP 和 VDMA IP,总有一种遗憾,那就是不够灵活,还需要对寄存器配置,真是麻烦。对于我们搞 FPGA 的人来说,最喜欢直接了当,直接用FPGA代码搞定。现在XILINX 的总线接口是AXI4总线…

Openai革新AI陪伴赛道?国内的AI陪伴创业公司有哪些?

人是一切社会关系的总和&#xff0c;而人的这种社会关系又依靠着情感来联系的。但是自从陪伴式AI的出现仿佛就打破了这种传统的关系。 在你的身边有这样一个“人”&#xff0c;她善解人意、风趣幽默&#xff0c;不会发脾气还会随时陪伴着你&#xff0c;这一在科幻电影中才会出现…

UE5 CommonUI的使用(附源码版)

UE5 CommonUI的使用 前言快速配置配置Game Viewport Client ClassCommonGameViewportClient源代码 创建CommonInputAction表默认导航Action设置CommonUIInputData源码 Bind CommonInputBaseControllerDataCommonInputBaseControllerData源码 Common UI控件库和控件样式CommonUs…

【JavaScript】P2 JavaScript 书写位置

本博文总结&#xff1a; JavaScript 书写位置&#xff1a; 内部外部行内 注意事项&#xff1a; 书写的位置尽量写到 </body> 之前外部 js 标签中间不写任何内容&#xff0c;因为不予以展示 正文&#xff1a; 交互效果示例 一个简单的交互效果示例&#xff1b; <…

[Halcon学习笔记]Halcon窗口进行等比例显示图像

目录 需求分析Halcon显示原理显示实现具体实现Halcon代码 需求分析 在使用Halcon加载图像时&#xff0c;点击Halcon的适应窗口&#xff0c;图像都会按照窗口大小对图像进行拉伸后显示&#xff0c;实际项目中&#xff0c;需要等比例显示图像&#xff0c;体现图像原本的尺寸细节…

Java对象的揭秘

前言 作为一个 Java 程序员&#xff0c;我们在开发中最多的操作要属创建对象了。那么你了解对象多少&#xff1f;它是如何创建&#xff1f;如何存储布局以及如何使用的&#xff1f;本文将对 Java 对象进行揭秘&#xff0c;以及讲解如何使用 JOL 查看对象内存使用情况。 本文是基…

2024最新版本激活Typora,1.8.10.0版本可用

实测可用日期为&#xff1a;2024-05-28 目前最新版本 1.8.10.0 也是可以实现激活的 注&#xff1a;免修改注册表、不用修改时间&#xff0c;更不需要破解补丁 01、下载&安装 Typora 文件 从官网下载最新版本的 Typora&#xff0c;并安装 或者阿里云盘&#xff1a; htt…

博客系统多模块开发

创建工程 创建父工程 删除src目录&#xff0c;在pom.xml添加依赖&#xff1a; <!--统一版本 字符编码--><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.b…

Git 小白入门到进阶—(基本概念和常用命令)

一.了解 Git 基本概念和常用命令的作用 (理论) 基本概念 1、工作区 包含.git文件夹的目录&#xff0c;主要用存放开发的代码2、仓库 分为本地仓库和远程仓库&#xff0c;本地仓库是自己电脑上的git仓库(.git文件夹);远程仓库是在远程服务器上的git仓库git文件夹无需我们进行操…

一些硬件知识【九】

STM32CUBEMX配置教程&#xff08;六&#xff09;高级定时器单通道输出互补PWM波&#xff08;带死区和刹车&#xff09;_高级定时器死区刹车怎么与电机模块连接?-CSDN博客 MOS选型关键参数&#xff1a; 额定电压&#xff0c;额定电流&#xff0c;导通电阻&#xff0c;阀值电压…

如何通过中间人攻击嗅探SIM卡的流量通信

写在前面的话 这篇文章我将介绍如何制作中间人&#xff08;MitM&#xff09;设置来嗅探SIM卡和后端服务器之间的流量。虽然这不是一项新的研究&#xff0c;但我希望这将帮助一些没有电信基础的人学习移动数据嗅探和虚假基站的知识。但是我只会介绍使用2G和GPRS的SIM卡的方案。…

防止特权升级攻击的有效策略

防止特权升级攻击的有效策略 特权升级攻击是一种通过利用操作系统或应用程序中的编程错误、漏洞、设计缺陷、配置错误或访问控制缺陷&#xff0c;获得对原本应该被限制访问的资源进行未授权访问的行为。这种攻击方式可能导致攻击者获取敏感数据、安装恶意软件并发动其他网络攻…

揭秘网络编程:同步与异步IO模型的实战演练

摘要 ​ 在网络编程领域&#xff0c;同步(Synchronous)、异步(Asynchronous)、阻塞(Blocking)与非阻塞(Non-blocking)IO模型是核心概念。尽管这些概念在多篇文章中被广泛讨论&#xff0c;它们的抽象性使得彻底理解并非易事。本文旨在通过具体的实验案例&#xff0c;将这些抽象…

Python + adb 实现打电话功能

前言 其实很多年前写过一篇python打电话的功能&#xff0c;链接如下&#xff1a; Python twilio 实现打电话和发短信功能_自动发短信代码-CSDN博客 今天由于工作需要&#xff0c;又用python写了个关于打电话的小工具&#xff0c;主要是通过ADB方式实现的 实现过程 1.先利用…

抖店重磅新规!保证金下调,一张营业执照能开多个店铺了!

哈喽~我是月月 抖音平台为助力小商家实现开店低成本&#xff0c;轻负担&#xff0c;高收益的模式 在5月30日正式实施了两个政策&#xff1a;保证金下调&#xff0c;一证多开 政策一&#xff1a;保证金下调 这次政策&#xff0c;涉及的类目优惠包含了&#xff0c;平台近70%的…