RabbitMq-队列交换机绑定关系优化为枚举注册

📚目录

  • 📚简介:
  • 🚀比较
    • 💨通常注册
    • 🌈优化后注册
  • ✍️代码
    • 💫自动注册的关键代码

📚简介:

       该项目介绍,rabbitMq消息中间件,对队列的注册,交换机的注册,队列与交换机的绑定关系进行注册,这三个步骤进行简化,通过枚举的配置完成这些操作。可以参考之前写的文章>SpringBoot整合Rabbitmq

🚀比较

💨通常注册

通常我们创建一个队列至少三个步骤

  1. 声明队列
  2. 声明交换机
  3. 队列绑定到交换机上,并且且设置路由关键字

在这里插入图片描述

🌈优化后注册

      我们只需要关注我们的队列枚举,里面已经定义好了通用配置,只有队列名称,交换机,交换机类型的指定我们需要自己定义外,之后的注册不需要你们关注即可完成。

在这里插入图片描述

✍️代码

💫自动注册的关键代码

RabbitMqConfig

代码的运行逻辑

  1. 应用启动:当 Spring Boot 应用启动时,RabbitAdmin Bean 会被初始化并启动。
  2. 队列和交换机的创建:在 createQueue 方法中,代码会遍历所有的队列枚举,将每个队列的相关配置(如交换机类型、持久性等)传递给相应的方法,创建所需的队列和交换机。
  3. 完成配置:一旦所有的交换机和队列创建完成,它们之间的绑定关系也会被设置好,从而确保消息可以在它们之间正确地流动。
/**
 * @author itmei
 */
@Configuration
public class RabbitMqConfig {

    ///**
    // * 声明队列
    // * @return
    // */
    //@Bean
    //public Queue directQueue(){
    //    //持久 - 如果我们声明一个持久队列,则为真(该队列将在服务器重启后继续存在)
    //    return new Queue(RabbitMqQueueEnum.DEFAULT_DIRECT.getQueueName(),false);
    //}
    //
    ///**
    // * 声明交换机
    // * @return
    // */
    //@Bean
    //public DirectExchange directExchange(){
    //    //交换器名称、是否持久化、是否自动删除
    //    return new DirectExchange(RabbitMqQueueEnum.DEFAULT_DIRECT.getExchangeName(),true,false);
    //}
    //
    ///***
    // * 队列绑定到交换机上
    // * 并且设置路由关键字
    // */
    //@Bean
    //public Binding binding(Queue queue,DirectExchange exchange){
    //    return BindingBuilder.bind(queue).to(exchange).with(RabbitMqQueueEnum.DEFAULT_DIRECT.getRoutingKey());
    //}

    
    /**
     * 用于动态创建队列和交换机
     * @param rabbitTemplate rabbitMq的模板对象
     * @return
     */
    @Bean
    public RabbitAdmin rabbitAdmin(RabbitTemplate rabbitTemplate){
        RabbitAdmin rabbitAdmin = new RabbitAdmin(rabbitTemplate);
        //默认就是true
        rabbitAdmin.setAutoStartup(true);
        return rabbitAdmin;
    }

    /**
     * 绑定
     * @param rabbitAdmin RabbitAdmin 实例,用于管理队列和交换机的声明
     * @return
     */
    @Bean("createQueue")
    public Object createQueue(RabbitAdmin rabbitAdmin) {
        // 遍历队列枚举
        RabbitMqQueueEnum.toList().forEach(rabbitMqQueueEnum -> {
            //创建交换机
            createExchangeHandle(rabbitAdmin,rabbitMqQueueEnum);
            // 创建对列
            createQueueHandle(rabbitAdmin,rabbitMqQueueEnum);
            // 绑定交换机和对列
            createBindingHandle(rabbitAdmin,rabbitMqQueueEnum);
        });
        return null;
    }


    /**
     * 注册交换机的方法,根据传入的队列枚举配置创建相应类型的交换机。
     * @param rabbitAdmin RabbitAdmin 实例,用于管理队列和交换机的声明
     * @param rabbitMqQueueEnum 自定义队列枚举,包含交换机的配置信息,包含交换机的配置信息
     */
    private void createExchangeHandle(RabbitAdmin rabbitAdmin, RabbitMqQueueEnum rabbitMqQueueEnum) {
        // 获取当前队列的交换机配置
        ExchangeConfigEnum exchangeConfigEnum = rabbitMqQueueEnum.getExchangeConfigEnum();
        String exchangeName = rabbitMqQueueEnum.getExchangeName();

        // 检查是否为延迟交换机
        if (rabbitMqQueueEnum.isDelayedExchange()) {
            // 创建并声明延迟交换机
            rabbitAdmin.declareExchange(new CustomDelayedExchange(
                    // 交换机名称
                    exchangeName,
                    // 交换机是否持久化
                    exchangeConfigEnum.isDurable(),
                    // 交换机是否自动删除
                    exchangeConfigEnum.isAutoDelete(),
                    // 交换机类型
                    exchangeConfigEnum.getType().name().toLowerCase()
            ));
        } else {
            // 创建并声明普通交换机
            createStandardExchange(rabbitAdmin, exchangeName, exchangeConfigEnum);
        }
    }

    /**
     * 创建并声明标准交换机的方法。
     * @param rabbitAdmin RabbitAdmin 实例,用于声明交换机
     * @param exchangeName 交换机的名称
     * @param exchangeConfigEnum 交换机的配置枚举,包含持久化和自动删除等信息
     */
    private void createStandardExchange(RabbitAdmin rabbitAdmin, String exchangeName, ExchangeConfigEnum exchangeConfigEnum) {
        AbstractExchange exchange;

        // 根据交换机类型创建对应的交换机实例
        switch (exchangeConfigEnum.getType()) {
            case FANOUT:
                // 创建 Fanout 交换机
                exchange = new FanoutExchange(exchangeName, exchangeConfigEnum.isDurable(), exchangeConfigEnum.isAutoDelete());
                break;
            case TOPIC:
                // 创建 Topic 交换机
                exchange = new TopicExchange(exchangeName, exchangeConfigEnum.isDurable(), exchangeConfigEnum.isAutoDelete());
                break;
            case DIRECT:
                // 创建 Direct 交换机
                exchange = new DirectExchange(exchangeName, exchangeConfigEnum.isDurable(), exchangeConfigEnum.isAutoDelete());
                break;
            default:
                // 不支持的交换机类型,直接返回
                return;
        }

        // 声明创建的交换机
        rabbitAdmin.declareExchange(exchange);
    }

    /**
     * 注册队列
     * @param rabbitAdmin RabbitAdmin 实例,用于管理队列和交换机的声明
     * @param rabbitMqQueueEnum 自定义队列枚举,包含交换机的配置信息
     */
    public void createQueueHandle(RabbitAdmin rabbitAdmin, RabbitMqQueueEnum rabbitMqQueueEnum) {
        QueueConfigEnum queueEnum = rabbitMqQueueEnum.getQueueConfigEnum();
        rabbitAdmin.declareQueue(new Queue(rabbitMqQueueEnum.getQueueName(),
                queueEnum.isDurable(), queueEnum.isExclusive(), queueEnum.isAutoDelete(), queueEnum.getArguments()));

    }

    /**
     * 注册绑定关系
     * @param rabbitAdmin RabbitAdmin 实例,用于管理队列和交换机的声明
     * @param rabbitMqQueueEnum 自定义队列枚举,包含交换机的配置信息
     */
    public void createBindingHandle(RabbitAdmin rabbitAdmin, RabbitMqQueueEnum rabbitMqQueueEnum) {
        // 绑定
        rabbitAdmin.declareBinding(new Binding(
                // queue名称
                rabbitMqQueueEnum.getQueueName(),
                Binding.DestinationType.QUEUE,
                // exchange名称
                rabbitMqQueueEnum.getExchangeName(),
                // queue的routingKey
                rabbitMqQueueEnum.getRoutingKey(),
                null));
    }

    /**
     * 用于创建延迟队列的交换机
     */
    public static class CustomDelayedExchange extends CustomExchange {
        public CustomDelayedExchange(String name, boolean durable, boolean autoDelete, String delayedType) {
            super(name, "x-delayed-message", durable, autoDelete, Collections.singletonMap("x-delayed-type", delayedType));
        }
    }
}

交换机枚举配置

/**
 * @Author itmei
 */
@Getter
@AllArgsConstructor
public enum ExchangeConfigEnum {
    /**
     * 直接模式
     */
    DIRECT_EXCHANGE(ExchangeModelEnum.DIRECT, true, false),

    /**
     * 匹配模式
     */
    TOPIC_EXCHANGE(ExchangeModelEnum.TOPIC, true, false),

    ;


    /**
     * 模式
     */
    private final ExchangeModelEnum type;

    /**
     * 是否持久化
     */
    private final boolean durable;

    /**
     * 是否自动删除
     */
    private final boolean autoDelete;

}

交换机枚举类型

/**
 * @Author itmei
 */
@Getter
@AllArgsConstructor
public enum ExchangeModelEnum {

    /**
     * 广播
     */
    FANOUT,

    /**
     * 匹配
     */
    TOPIC,

    /**
     * 直接模式
     */
    DIRECT
}

默认队列配置

/**
 * @author itmei
 */
@Getter
@AllArgsConstructor
public enum QueueConfigEnum {
    /**
     * 自定义的队列配置
     */
    DEFAULT_QUEUE_CONFIG(true, false, false, null),
    ;


    /**
     * 是否为持久队列(该队列将在服务器重启后保留下来)
     */
    private final boolean durable;

    /**
     * 是否为排他队列(该队列仅由声明者的队列使用连接)
     */
    private final boolean exclusive;

    /**
     * 如果队列为空是否删除(如果服务器在不再使用队列时是否删除队列)
     */
    private final boolean autoDelete;

    /**
     * queue的参数
     */
    private final Map<String, Object> arguments;


}

自定义队列配置(以后只需要把队列增加到这里即可)


/**
 * @author itmei
 */
@Getter
@AllArgsConstructor
public enum RabbitMqQueueEnum {
    /**
     * 自定义的队列与交换机的关系
     */

    DEFAULT_DIRECT("direct_itmei_exchange",
            "direct.itmei.exchange.default.queue",
            "direct.itmei.exchange.default.queue",
            ExchangeConfigEnum.DIRECT_EXCHANGE,
            QueueConfigEnum.DEFAULT_QUEUE_CONFIG,
            true,
            "默认队列"
    ),
    DEFAULT_TEST_DIRECT("direct_itmei_exchange",
            "direct.itmei.exchange.test.queue",
            "direct.itmei.exchange.test.queue",
            ExchangeConfigEnum.DIRECT_EXCHANGE,
            QueueConfigEnum.DEFAULT_QUEUE_CONFIG,
            true,
            "测试对列"
    ),

    ;

    /**
     * 交换机名称
     */
    private final String exchangeName;

    /**
     * 队列名称(每个队列的名称应是唯一的)
     */
    private final String queueName ;

    /**
     * 默认保持和对列名称一样,模式为 topic时需要注意匹配符设置
     * 队列路由键(
     *  注意匹配,#匹配一个或者多个,*匹配一个
     *      如: abc.new.n , abc.new.n.m
     *      abc.new.# 匹配{abc.new.n,abc.new.n.m}
     *      abc.new.* 匹配{abc.new.n}
     * )
     */
    private final String routingKey;

    /**
     * 交换机的配置
     */
    private final ExchangeConfigEnum exchangeConfigEnum;

    /**
     * 对列的配置
     */
    private final QueueConfigEnum queueConfigEnum;

    /**
     * 是否是延迟交换机 如果已经存在不是延迟交换机则需要删除再标记
     * treu:延迟交换机 false:普通交换机
     */
    private final boolean delayedExchange;

    /**
     * 描述
     */
    private final String desc;

    public static List<RabbitMqQueueEnum> toList() {
        return Arrays.asList(RabbitMqQueueEnum.values());
    }

}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SQL进阶技巧:如何求组内排除当前行的移动平均值?

目录 0 需求描述 2 数据准备 3 问题分析 4 小结 0 需求描述 -- 按照 日期,省份,等级 分组 求分数的平均值;但是需要剔除当前行的数据 2 数据准备 create table avgtest as (select 2024-10-24 as cdate, 广东 as province,深圳 as city, 2 as level, 200 as scoreunio…

雷池社区版OPEN API使用教程

OPEN API使用教程 新版本接口支持API Token鉴权 接口文档官方没有提供&#xff0c;有需要可以自行爬取&#xff0c;爬了几个&#xff0c;其实也很方便 使用条件 需要使用默认的 admin 用户登录才可见此功能版本需要 > 6.6.0 使用方法 1.在系统管理创建API TOKEN 2.发…

基于SSM+小程序的汽车保养登录管理系统(汽车1)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于SSM小程序的汽车保养登录管理系统实现了管理员及用户。 1、管理员实现了管理门店和其对应的员工&#xff0c;管理保养信息和汽车配件信息&#xff0c;管理各种状态的订单。 2、用户…

offset Explorer连接云服务上的kafka连接不上

以上配置后报连接错误时&#xff0c;可能是因为kafka的server.properties配置文件没配置好&#xff1a; 加上面两条配置&#xff0c;再次测试连接&#xff0c;成功 listeners和advertised.listeners

若依部署上线遇到的问题

一、若依部署上线的用户头像模块不能回显&#xff1a; 首先是后端修改部署上线后若依存储图片的本地地址 其次将上线前端配置文件中的图片相关配置给删除 二、若依部署上线后验证码不显示问题 在确保前后端请求打通后还有这个问题就是磁盘缓存问题 三、若依部署上线遇到404页…

雷池社区版中升级雷池遇到问题

关于升级后兼容问题 版本差距过大会可能会发生升级后数据不兼容导致服务器无法起来 跨多个版本&#xff08;超过1个大版本号&#xff09;升级做好数据备份&#xff0c;遇到升级失败可尝试重新安装解决 升级提示目录不对 在错误的目录下执行&#xff08;比如 safeline 的子目…

Navicat导入Excel数据时数据被截断问题分析与解决方案

目录 前言1. 问题分析1.1 默认字段类型的影响1.2 MySQL诊断机制的限制 2. 解决方案2.1 修改字段长度2.2 修改Excel数据以影响推断2.3 检查导入工具的设置 3. 其他注意事项3.1 注册表的修改3.2 增加自增ID 4. 结语 前言 在数据库的日常操作中&#xff0c;将Excel数据导入MySQL是…

Android Junit 单元测试 | 依赖配置和编译报错解决

问题 为什么在依赖中添加了testImplement在build APK的时候还是会报错&#xff1f;是因为没有识别到test文件夹是test源代码路径吗&#xff1f; 最常见的配置有: implementation - 所有源代码集(包括test源代码集)中都有该依赖库.testImplementation - 依赖关系仅在test源代码…

前端代码分享--爱心

给对象写的&#xff0c;顺便源码给大家分享一下 就是简单的htmlcssjs&#xff0c;不复杂 xin1.html <!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"UTF-8"> <title>写你自己的</title> <lin…

buildroot制作自己的软件包(可以理解为应用程序)

以helloworld为例记录使用步骤 一&#xff1a;书写自己的源程序以及Makefile helloworld.c #include <stdio.h>int main(int argc, char **argv) {printf("hello world\r\n");return 0; }Makefile all: helloworldhelloworld: helloworld.o$(CC) -o hellow…

关于嵌入式学习的一些短浅经验

一、写在前面 感谢在 10.23&#xff0c;各位大佬对我进行的模拟面试&#xff0c;我也发现了我对知识的不熟练的部分&#xff0c;比如 IPC 方法和线程同步方法的知识。模拟面试第四期-已经拿到大厂 OFFER 的研究生大佬-LINUX 卷到飞起_哔哩哔哩_bilibili 然后&#xff0c;沈阳…

OpenRTP 传输增加OpenRTPServer

开源地址 最近增加了OpenRTPServer&#xff0c; 已经修改完成一版放在了目录下&#xff0c;window和linux下编译都成功了&#xff0c;不过由于修改代码CMakefile 需要修改&#xff0c;先放放 OpenRTP开源地址 vlc得纠错传输方式 我发现我代码写错以后&#xff0c;vlc 依然能…

重要:民族共同体精品课格式说明

铸牢中华民族共同体意识精品课以微课形式呈现&#xff0c;包括微课 视频、教学设计讲义、课件等。 微课视频 微课视频应采用“教师讲解多媒体大屏”的形式&#xff0c;适当呈现授课教师画面&#xff0c;增强教学的交互性和画面的可视性。单个微课视频时长&#xff1a;高校专题…

【已解决】cannot import name ‘Literal‘ from ‘typing‘

问题描述 在用vscode进行debug的时候&#xff0c;报错cannot import name Literal from typing 解决方法 方法一&#xff1a;升级Python版本到3.8以上 我的python版本是3.7&#xff0c;但由于环境都配好了&#xff0c;升级太麻烦&#xff0c;没采用该方法 方法二&#xff1…

C++和Java该如何进行选择?

曾经的自己与许多C程序员都有着一样的盲目自信&#xff1a;认为掌握了C&#xff0c;在去学习Java上手会容易很多。 到底是谁给了你这种勇气和自信&#xff1f; 很多人经常会说&#xff0c;Java这种通过虚拟机运行的语言&#xff0c;虚拟机本身就是C开发的&#xff0c;根本就没…

Java 多线程(九)—— JUC 常见组件 与 线程安全的集合类

Callable 与 FutureTask Callable 接口和 Runnable 接口是并列关系&#xff0c;都是用来给线程提供任务的&#xff0c;只不过 Callable 接口的任务可以带有返回值。 但是 Callable 接口创建的任务不能直接传入 Thread 里面&#xff0c;这也是为了 解耦合&#xff0c;我们可以使…

pdf合并,这4款好用软件分分钟解决问题!

PDF作为一种跨平台、不易被篡改的文档格式&#xff0c;广泛应用于工作、学习和日常生活中。然而&#xff0c;当面对多个PDF文件需要合并成一个时&#xff0c;繁琐的手动操作往往让人头疼不已。别担心&#xff0c;今天就给大家安利4款超实用的PDF合并软件&#xff0c;它们不仅操…

c++二级指针

如果要通过函数改变一个指针的值&#xff0c;要往函数中传入指针的指针 如果要通过函数改变一个变量的值&#xff0c;那就要往函数中传入这个变量的地址 改变a的值和b的值 #include <iostream>using namespace std;void swap(int* a, int* b) {int temp *a;*a *b;*b …

pyvideotrans 最佳AI翻译软件

文章目录 体验视频翻译配音工具主要用途和功能预打包版本(仅win10/win11可用&#xff0c;MacOS/Linux系统使用源码部署)MacOS源码部署Linux 源码部署Window10/11 源码部署源码部署问题说明使用教程和文档语音识别模型:视频教程(第三方)软件预览截图相关联项目致谢 体验 不错&a…

根据Redis漏洞通知的整改修复过程

一、收到通知&#xff1a; 二、查看本校“宝山商城&#xff08;教学&#xff09;”已安装的Redis版本号 对照影响范围的版本号&#xff0c;在其内&#xff0c;所以需要升级Redis版本。 三、升级centos中的Redis版本 在Cent0S系统中&#xff0c;如果我们需要升级Redis版本&…