Spring AMQP如何通过配置文件避免硬编码实现解耦

        在使用Spring AMQP基于注解声明监听者时,可通过抽取常量来避免硬编码:

@RabbitListener(bindings = @QueueBinding(exchange = @Exchange(MQConstant.USER_EXCHANGE),value = @Queue(MQConstant.USER_QUEUE),key = MQConstant.USER_REDIS_BINDING))public void deleteUserInfoRedisByExchange(String message) {log.info("监听到消息message:{}", message);}
rabbitTemplate.convertAndSend(MQConstant.USER_EXCHANGE, MQConstant.USER_REDIS_BINDING, message);

        这种方式方便快捷,在以后修改时可通过修改常量类即可。下面介绍一种基于编程式声明监听者并通过配置文件(yml)进行修改的方式避免硬编码。

配置yml文件(或properties文件),自定义交换机、队列:

hl:amqp:# RabbitMQ交换机名称exchanges:userExchange:name: css.user.exchangetype: directdurable: true# 队列名称queues: userQueue:name: css.user.redis.loginUser.queuedurable: trueexclusive: falseautoDelete: false# 绑定关系    bindings:userRedisBinding:exchange: ${hl.amqp.exchanges.userExchange.name}queue: ${hl.amqp.queues.userQueue.name}routingKey: user.redis.loginUser.del

创建properties读取yml文件:

import java.util.Map;import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;import lombok.Data;/***  RabbitMQ配置属性类*/
@Component
@ConfigurationProperties(prefix = "hl.amqp")
@Data
public class AmqpConfigProperties {private Map<String, ExchangeConfig> exchanges;private Map<String, QueueConfig> queues;private Map<String, BindingConfig> bindings;@Datapublic static class ExchangeConfig {private String name;private String type;private boolean durable = true;private boolean autoDelete = false;private boolean internal = false;}@Datapublic static class QueueConfig {private String name;private boolean durable = true;private boolean exclusive = false;private boolean autoDelete = false;}@Datapublic static class BindingConfig {private String exchange;private String queue;private String routingKey;}
}

创建动态加载配置类,进行交换机,队列和绑定关系的注册:

import com.hl.campusservicesys.properties.AmqpConfigProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.HashMap;
import java.util.Map;@Slf4j
@Configuration
public class DynamicAmqpConfig {private final AmqpAdmin amqpAdmin;private final AmqpConfigProperties amqpConfigProperties;// 改为构造器注入或方法注入public DynamicAmqpConfig(AmqpAdmin amqpAdmin, AmqpConfigProperties amqpConfigProperties) {this.amqpAdmin = amqpAdmin;this.amqpConfigProperties = amqpConfigProperties;}// 创建交换机@Beanpublic Map<String, Exchange> amqpExchanges() {Map<String, Exchange> exchanges = new HashMap<>();amqpConfigProperties.getExchanges().forEach((key, config) -> {Exchange exchange = switch (config.getType()) {case ExchangeTypes.DIRECT -> new DirectExchange(config.getName(), config.isDurable(), config.isAutoDelete());case ExchangeTypes.TOPIC -> new TopicExchange(config.getName(), config.isDurable(), config.isAutoDelete());case ExchangeTypes.FANOUT -> new FanoutExchange(config.getName(), config.isDurable(), config.isAutoDelete());default -> throw new IllegalArgumentException("Unsupported exchange type: " + config.getType());};exchanges.put(key, exchange);// 直接通过amqpAdmin声明交换机到RabbitMQamqpAdmin.declareExchange(exchange);});log.info("RabbitMQ交换机初始化完成!");return exchanges;}// 创建队列@Beanpublic Map<String, Queue> amqpQueues() {Map<String, Queue> queues = new HashMap<>();amqpConfigProperties.getQueues().forEach((key, config) -> {Queue queue = new Queue(config.getName(),config.isDurable(),config.isExclusive(),config.isAutoDelete());queues.put(key, queue);// 直接通过amqpAdmin声明队列到RabbitMQamqpAdmin.declareQueue(queue);});log.info("RabbitMQ队列初始化完成!");return queues;}// 创建绑定关系@Beanpublic Map<String, Binding> amqpBindings(Map<String, Exchange> amqpExchanges, Map<String, Queue> amqpQueues) {Map<String, Binding> bindings = new HashMap<>();amqpConfigProperties.getBindings().forEach((key, config) -> {// 查找对应的交换机和队列Exchange exchange = null;for (Exchange ex : amqpExchanges.values()) {if (ex.getName().equals(config.getExchange())) {exchange = ex;break;}}Queue queue = null;for (Queue q : amqpQueues.values()) {if (q.getName().equals(config.getQueue())) {queue = q;break;}}if (exchange != null && queue != null) {Binding binding = BindingBuilder.bind(queue).to(exchange).with(config.getRoutingKey()).noargs();bindings.put(key, binding);// 直接通过amqpAdmin声明绑定关系到RabbitMQamqpAdmin.declareBinding(binding);}});log.info("RabbitMQ绑定关系初始化完成!");return bindings;}@Beanpublic Jackson2JsonMessageConverter jackson2JsonMessageConverter() {return new Jackson2JsonMessageConverter();}// 配置消息转换器@Beanpublic MessageConverter messageConverter(){// 1.定义消息转换器Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();// 2.配置自动创建消息id,用于识别不同消息,也可以在业务中基于ID判断是否是重复消息jackson2JsonMessageConverter.setCreateMessageIds(true);return jackson2JsonMessageConverter;}// 配置 RabbitTemplate@Beanpublic RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory, Jackson2JsonMessageConverter messageConverter) {RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);rabbitTemplate.setMessageConverter(messageConverter);return rabbitTemplate;}}

配置消息监听器:

/*** 用户服务监听器* */
@Slf4j
@Component
public class UserListener {@Resourceprivate RedisCache redisCache;@RabbitListener(queues = "${hl.amqp.queues.userQueue.name}")public void deleteUserInfoRedis(Long userId) {log.info("监听到消息message:{}", userId);redisCache.deleteObject(RedisConstant.USER_INFO_KEY + userId);}}

创建消息发送者:

/*** RabbitMQ工具类* */
@Component
public class AmqpMessageSender {@Autowiredprivate RabbitTemplate rabbitTemplate;@Autowiredprivate AmqpConfigProperties amqpConfigProperties;/*** 发送消息* @param exchange 交换机配置键名* @param routingKey 路由键* @param message 消息内容*/public void sendMessage(String exchange, String routingKey, Object message) {rabbitTemplate.convertAndSend(amqpConfigProperties.getExchanges().get(exchange).getName(),amqpConfigProperties.getBindings().get(routingKey).getRoutingKey(), message);rabbitTemplate.convertAndSend(MQConstant.USER_EXCHANGE, MQConstant.USER_REDIS_BINDING, message);}}

创建常量类:

/*** MQ常量* */
public class MQConstant {public static final String USER_EXCHANGE = "userExchange";public static final String USER_QUEUE = "userQueue";public static final String USER_REDIS_BINDING = "userRedisBinding";
}

 使用:

// 发送消息更新缓存
amqpMessageSender.sendMessage(MQConstant.USER_EXCHANGE, MQConstant.USER_REDIS_BINDING, userDTO.getUserId());

示例:

启动时完成初始化:

发送消息,监听者接收并处理:

        在启动时,spring会自动加载注册配置的交换机、队列并完成绑定,对比下来肯定是没直接使用常量类方便来着,感兴趣可以玩玩。

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

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

相关文章

解决zabbix图片中文乱码

要把 Zabbix 前端字体替换为 simkai.ttf&#xff08;楷体&#xff0c;解决乱码常用&#xff09;&#xff0c;按以下步骤操作&#xff1a;1. 确认 simkai.ttf 路径 先找到系统里 simkai.ttf 字体文件&#xff0c;若没有&#xff0c;可从 Windows 系统&#xff08;C:\Windows\Fon…

实例分割-动手学计算机视觉13

介绍 实例分割(instance segmentation)的目的是从图像中分割出每个目标实例的掩模(mask)。与语义分割相比&#xff0c;实例分割不但要区分不同的类别&#xff0c;还要区分出同一种类别下的不同目标实例。如图13-1所示 语义分割的结果中&#xff0c;不同的羊对应的标签是一样的…

水环境遥感分析!R语言编程+多源遥感数据预处理;水体指数计算、水深回归分析、水温SVM预测、水质神经网络建模及科研级可视化制图

系统性地整合R语言编程、遥感数据处理及机器学习建模&#xff0c;涵盖水线提取&#xff08;水体指数与阈值法&#xff09;、水深反演&#xff08;多元回归&#xff09;、水温预测&#xff08;支持向量机&#xff09;、水质评估&#xff08;神经网络&#xff09;等核心内容&…

微信公众号/小程序百万级OpenID自动化获取工具

摘要 本报告详细阐述了微信用户列表数据获取与处理工具的设计思路,包括分页处理机制、频率控制策略、断点续传功能和分布式存储方案。针对微信API调用限制和用户数据规模特点,该工具旨在高效、安全地获取和存储微信用户列表数据,同时严格遵守微信API调用频率限制,确保系统…

物联网系统中传感器到网关到物联网平台的传输路径、协议、原理、用途与架构详解

摘要物联网&#xff08;IoT&#xff09;系统通过传感器、网关和物联网平台实现数据的采集、传输、处理和应用。本文详细分析了传感器到网关再到物联网平台的传输路径&#xff0c;涵盖直接连接、网关中继、边缘计算、多级网关和混合路径五种方式&#xff1b;介绍了短距离&#x…

SpringBoot自动注入配置类初步实现

一.SpringBoot自动装配SpringBoot 的 自动装配&#xff08;Auto-Configuration&#xff09; 是它的核心特性之一&#xff0c;它让开发者可以 "开箱即用"&#xff0c;避免手动配置大量的 XML 或 Java Config。它的核心思想是&#xff1a;"约定优于配置"&…

直播预告|鸿蒙生态中的AI新玩法

想知道鸿蒙生态里 AI 能玩出啥新花样&#xff1f; 8 月 14 日&#xff08;周四&#xff09;20:00 &#xff0c;「开发者・面对面 坚果派特辑 —— 鸿蒙生态中的 AI 新玩法」直播来袭&#xff01; &#x1f50d; 直播亮点抢先看 AI赋能鸿蒙产品开发&#xff1a;将分享如何利用AI…

智能合约:区块链时代的“数字契约革命”

一、技术原理与核心特征1. 定义与本质智能合约是运行在区块链上的自动化程序&#xff0c;通过代码定义业务规则&#xff0c;在预设条件满足时自动执行操作&#xff08;如资金转移、信息更新&#xff09;&#xff0c;无需人工干预。其核心特性包括&#xff1a;自动执行&#xff…

【数据分析】比较SparCC、Pearson和Spearman相关性估计方法在合成组学数据上的表现

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍 加载R包 模拟数据 构建网络 RMSE指数计算 画图 总结 系统信息 介绍 在生物信息学和生态学研究中,组学数据的分析越来越依赖于对微生物群落或基因表达数据中物种或基因间相关性的…

Google C++ 风格指南

文章目录背景介绍风格指南的目标C 版本头文件自包含头文件#define 防护包含所需内容前置声明在头文件中定义函数头文件包含顺序与命名规范作用域命名空间内部链接非成员函数、静态成员函数与全局函数局部变量静态与全局变量关于析构的决策关于初始化的决策常见模式thread_local…

安装部署_WVP流媒体

文章目录一、DEV_WVP流媒体开发手册1、搭建流媒体服务clone代码&#xff1a;安装编译器cmake构建和编译项目修改配置文件启动项目2、搭建GB28181协议视频平台安装 jdk, nodejs, maven, git安装redis安装postgresqlclone代码编译前端代码编译后端代码配置文件修改3、设备接入测测…

软件I2C实现(2):I2C协议实现

0 参考资料 I2C 总线规范.pdf 1 I2C协议实现 1.1 SCL、SDA引脚初始化 将SCL、SDA初始化为开漏输出,电平设置为高电平(使用外部上拉电阻拉高)。 /*** @brief 软件I2C初始化** @param sw_i2c_cfg 软件I2C配置指针*/ int sw_i2c_init(sw_i2c_cfg_t *sw_i2c_cfg) {GPIO_InitT…

疯狂星期四文案网第40天运营日记

网站运营第40天&#xff0c;点击观站&#xff1a; 疯狂星期四 crazy-thursday.com 全网最全的疯狂星期四文案网站 运营报告 今日访问量 今日搜索引擎收录情况 必应秒发秒收 百度收录很慢 网站优化点 优化seo 修复已知bug

【大语言模型 01】注意力机制数学推导:从零实现Self-Attention

注意力机制数学推导&#xff1a;从零实现Self-Attention - 开启大语言模型的核心密码 关键词&#xff1a;注意力机制、Self-Attention、Transformer、数学推导、PyTorch实现、大语言模型、深度学习 摘要&#xff1a;本文从数学原理出发&#xff0c;详细推导Self-Attention的完整…

2025 环法战车科技对决!维乐 Angel Glide定义舒适新标

环法赛场不仅是顶尖车手的竞技舞台&#xff0c;更是自行车科技的时尚秀场。然而经常骑行的朋友都知道&#xff0c;当顶级战车遇上专业坐垫&#xff0c;方能成就完美骑行体验。2025 年环法赛场上的新战车们各展神通&#xff0c;而维乐 Angel Glide 坐垫以其独特的科技与设计&…

VS Code配置MinGW64编译ALGLIB库

VS Code用MinGW64编译C代码安装MSYS2软件并配置ALGLIB库和测试引用库代码的完整具体步骤。 1. 安装 MSYS2 下载 MSYS2&#xff1a; 访问 MSYS2 官网下载最新安装包&#xff08;如 msys2-x86_64-latest.exe&#xff09; 安装&#xff1a; 运行安装程序&#xff0c;默认路径为 C…

《WINDOWS 环境下32位汇编语言程序设计》第2章 准备编程环境

2.1 Win32可执行文件的开发过程 在DOS下&#xff0c;生成一个可执行文件的步骤比较简单&#xff0c;用编译器将源程序编译为obj文件&#xff0c;再用链接器将obj文件链接成exe文件&#xff0c;不同语言的开发过程都差不多。 DOS可执行文件中的内容是由源程序中所写的代码和数…

kubernetes(4) 微服务

一、什么是微服务在 Kubernetes 中&#xff0c;控制器负责维持业务副本&#xff0c;但真正把业务“暴露”出去的是 Service。 一句话理解&#xff1a;Service 一组 Pod 的稳定访问入口 4 层负载均衡Ingress 7 层路由 统一入口 灰度 / 认证 / 重写等高级能力默认情况下&…

Pandas 2.0 + Arrow 加速、Dask vs Ray、Plotly 可视化:数据分析的未来

在大数据与人工智能时代,数据分析与可视化的技术栈正在快速演进。过去十年,Pandas 几乎是数据科学家的“瑞士军刀”,Matplotlib 和 Seaborn 是最常用的可视化工具。但如今,随着数据规模与分析需求的增长,新的趋势正在出现: Pandas 2.0 引入 Apache Arrow 后端,性能显著提…

windows扩展(外接)显示器位置调节

概述有的时候我们想把屏幕往左或往右拖动&#xff0c;默认情况下&#xff0c;屏幕都是默认往右拖动的&#xff0c;如果想往左拖动&#xff0c;则需要进行设置。具体步骤如下&#xff1a;当然不止这些还可以往上调&#xff0c;下调等多个位置可调至&#xff0c;这里只显示左右调…