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
英文地址,請注明出處:http://en.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;這里只顯示左右調…