springboot集成spring-cloud-context手動刷新并讀取更新后的配置文件

背景

springboot單體項目在運行過程需要刷新springboot配置文件值,比如某個接口限流閾值,新增某個賬戶等場景。分布式設計的可以直接引入一些持久化中間件比如redis等,也可以用相關配置中心中間件如nacos等。處于成本等場景單體項目可以考慮①把配置文件緩存到java對象中,然后暴露出刷新配置文件接口②本文主要講如何利用spring-cloud-context組件快速實現手動更新配置文件。

原理

依賴

注意不同springboot版本和springcloud要對應https://spring.io/projects/spring-cloud#overview

pom.xml

    <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.12</version><relativePath/> <!-- lookup parent from repository --></parent><properties><java.version>1.8</java.version></properties><!--注意不同springboot版本和cloud要對應https://spring.io/projects/spring-cloud#overview--><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>2021.0.3</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-context</artifactId></dependency></dependencies>

配置文件

application.properties

server.refresh=${random.long}
server.key=${random.long}
config.uuid=${random.uuid}

代碼

演示@ConfigurationProperties和@value方式引入的兩種方式讀取配置文件的刷新

注意@value方式引入需要在對應類上添加@RefreshScope注解

ServerConfig.java

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Component
@ConfigurationProperties(prefix = "server")
@Data
public class ServerConfig {private String key;private Long refresh;
}

ValueConfig.java

import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;@RefreshScope// @Value這種方式必須標注此注解contextRefresher.refresh()后才會生效
@Component
@Data
public class ValueConfig {@Value("${config.uuid}")private String uuid;
}

測試接口DemoController.java

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.cloud.context.refresh.ContextRefresher;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.Set;@RestController
public class DemoController {@Autowiredprivate ContextRefresher contextRefresher;@Autowiredprivate ServerConfig serverConfig;@Autowiredprivate ValueConfig valueConfig;@GetMapping(path = "/show")public Object show() {// 取得的值不變return "serverConfig:"+serverConfig+" valueConfig:"+valueConfig;}@GetMapping(path = "/refresh")public Object refresh() {// 刷新后將獲取到刷新后的值 ,包括新增key,注意開發模式運行服務后編譯后的文件路徑,一般是在targetnew Thread(() -> {contextRefresher.refresh();}).start();return show();}
}

測試

訪問/refresh接口可以看到每次獲取的值不一樣,當然也可以手動更新配置文件的值(更新v、新增k-v、刪除k-v),注意開發模式手動更改是在編譯后的文件路徑,一般是在target下

serverConfig:ServerConfig(key=8733164433754704077, refresh=5118825739210703127) valueConfig:ValueConfig(uuid=ca7bceba-66ef-4ea4-a4f8-6caa027927f3)

拓展

如果想要配置文件更新后做一些其它動作,比如郵件通知下牛馬開發員,從可以從contextRefresher.refresh()源碼得知配置文件發送變更后會觸發this.context.publishEvent,利用spring的事件通知機制就可以實現了。了解更多@EventListener注解知識可以參考博客[https://blog.csdn.net/u012060033/article/details/136006082]

    @Configurationpublic class EnvConfiguration{@EventListenerpublic void envListener(EnvironmentChangeEvent event) {// 配置文件刷新會觸發此事件,key的變化可以通過event.getKeys()獲取System.out.println("conf change: " + event);}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75794.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75794.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75794.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

proteus8.17 環境配置

Proteus介紹 Proteus 8.17 是一款功能強大的電子設計自動化&#xff08;EDA&#xff09;軟件&#xff0c;廣泛應用于電子電路設計、仿真和分析。以下是其主要特點和新功能&#xff1a; ### 主要功能 - **電路仿真**&#xff1a;支持數字和模擬電路的仿真&#xff0c;包括靜態…

手機端可部署的開源大模型; 通義千問2.5訓練和推理需要的內存和外存

手機端可部署的開源大模型 目錄 手機端可部署的開源大模型Qwen2.5 0.5B 7b 推理采用手機內存需要多少Qwen2.5 0.5B不同量化精度下的內存需求Qwen2.5 7B不同量化精度下的內存需求通義千問2.5訓練和推理需要的內存和外存推理階段1. Qwen2.5 - 7B2. Qwen2.5 - 14B3. Qwen2.5 - 72B…

【uniapp-兼容性處理】swiper在iOS上偶發出現后幾張圖片白屏情況

【日期】2025-04-14 【問題】 swiper在iOS上偶發出現后幾張圖片白屏情況 swiper內部的幾個swiper-item垂直排列&#xff0c;各自進行滾動&#xff0c;樣式方面兼容性出現問題 【原因】&#xff1a; 原代碼&#xff1a;&#xff08;不應在swiper-item添加style屬性&#xf…

SpringBoot連接MQTT客戶端

引入依賴 <dependency><groupId>org.eclipse.paho</groupId><artifactId>org.eclipse.paho.client.mqttv3</artifactId><version>1.2.2</version> </dependency> 啟動類 SpringBootApplication public class AxiosDemoApplic…

HTML:網頁的骨架 — 入門詳解教程

HTML&#xff1a;網頁的骨架 — 入門詳解教程 HTML&#xff08;HyperText Markup Language&#xff0c;超文本標記語言&#xff09;是構建網頁的基礎語言&#xff0c;負責定義網頁的結構和內容。無論是簡單的個人博客&#xff0c;還是復雜的企業網站&#xff0c;HTML都是不可或…

212、【圖論】字符串接龍(Python)

題目描述 題目鏈接&#xff1a;110. 字符串接龍 代碼實現 import collectionsn int(input()) beginStr, endStr input().split() strList [input() for _ in range(n)]deque collections.deque() # 使用隊列遍歷結點 deque.append([beginStr, 1]) # 存儲當前字符串和遍…

操作系統導論——第19章 分頁:快速地址轉換(TLB)

使用分頁作為核心機制來實現虛擬內存&#xff0c;可能會帶來較高的性能開銷。使用分頁&#xff0c;就要將內存地址空間切分成大量固定大小的單元&#xff08;頁&#xff09;&#xff0c;并且需要記錄這些單元的地址映射信息。因為這些映射信息一般存儲在物理內存中&#xff0c;…

使用Apache POI(Java)創建docx文檔和表格

1、引入poi 依賴組件 <dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>4.0.0</version> </dependency> <dependency><groupId>org.apache.poi</groupId>&…

python cv2 安裝

在Python中安裝opencv-python&#xff08;即OpenCV庫&#xff09;&#xff0c;通常有兩種方法&#xff1a;使用pip命令或通過conda&#xff08;如果你使用的是Anaconda或Miniconda&#xff09;。以下是詳細的步驟&#xff1a; 方法1&#xff1a;使用pip 打開你的命令行界面&am…

讀者、寫者問題優化

#include <stdio.h> #include <time.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <semaphore.h> #define NUM_READERS 5 #define NUM_WRITERS 5 // 定義信號量和全局變量 sem_t sdata, srcount; int rea…

如何通過前端表格控件實現自動化報表?1

背景 最近伙伴客戶的項目經理遇見一個問題&#xff0c;他們在給甲方做自動化報表工具&#xff0c;項目已經基本做好了&#xff0c;但拿給最終甲方&#xff0c;業務人員不太買賬&#xff0c;項目經理為此也是天天抓狂&#xff0c;沒有想到合適的應對方案。 現階段主要面臨的問…

RabbitMQ 優先級隊列詳解

本文是博主在記錄使用 RabbitMQ 在執行業務時遇到的問題和解決辦法&#xff0c;因此查閱了相關資料并做了以下記載&#xff0c;記錄了優先級隊列的機制和使用要點。 本文為長文&#xff0c;詳細介紹了相關的知識&#xff0c;可作為學習資料看。 文章目錄 一、優先級隊列介紹1、…

代理模式簡述

目錄 一、主要角色 二、類型劃分 三、靜態代理 示例 缺點 四、動態代理 JDK動態代理 示例 缺點 CGLib動態代理 導入依賴 示例 五、Spring AOP 代理模式是一種結構型設計模式&#xff0c;通過代理對象控制對目標對象的訪問&#xff0c;可在不改變目標對象情況下增強…

每日一題——云服務計費問題

云服務計費問題&#xff08;哈希表 排序&#xff09;| 附詳細 C源碼解析 一、題目描述二、輸入描述三、輸出描述四、樣例輸入輸出輸入示例&#xff1a;輸出示例&#xff1a;說明&#xff1a; 五、解題思路分析六、C實現源碼詳解&#xff08;完整&#xff09;七、復雜度分析 一…

【JVM】運行時數據區域

文章目錄 1. 程序計數器補充 2. 虛擬機棧2.1 棧幀1. 局部變量表2. 操作數棧3. 動態鏈接4. 方法返回地址補充 3. 本地方法棧4. 堆5. 方法區靜態常量池&#xff08;Class常量池&#xff09;運行時常量池字符串常量池&#xff08;1&#xff09;位置變化&#xff08;2&#xff09;放…

day28圖像處理OpenCV

文章目錄 一、圖像預處理4 邊緣填充4.1 邊界復制&#xff08;BORDER_REPLICATE&#xff09;4.2 邊界反射&#xff08;BORDER_REFLECT&#xff09;4.3 邊界反射101&#xff08;BORDER_REFLECT_101&#xff09;4.4 邊界常數&#xff08;BORDER_CONSTANT&#xff09;4.5 邊界包裹&…

C++ Json-Rpc框架-3項目實現(2)

一.消息分發Dispatcher實現 Dispatcher 就是“消息分發中樞”&#xff1a;根據消息類型 MType&#xff0c;把消息派發給對應的處理函數&#xff08;Handler&#xff09;執行。 初版&#xff1a; #pragma once #include "net.hpp" #include "message.hpp"n…

C++算法優化實戰:破解性能瓶頸,提升程序效率

C算法優化實戰&#xff1a;破解性能瓶頸&#xff0c;提升程序效率 在現代軟件開發中&#xff0c;算法優化是提升程序性能的關鍵手段之一。無論是在高頻交易系統、實時游戲引擎&#xff0c;還是大數據處理平臺&#xff0c;算法的高效性直接關系到整體系統的性能與響應速度。C作…

【PostgreSQL教程】PostgreSQL 特別篇之 語言接口連接PHP

博主介紹:?全網粉絲22W+,CSDN博客專家、Java領域優質創作者,掘金/華為云/阿里云/InfoQ等平臺優質作者、專注于Java技術領域? 技術范圍:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大數據、物聯網、機器學習等設計與開發。 感興趣的可…

山東大學軟件學院創新項目實訓開發日志(12)之將對話記錄保存到數據庫中

在之前的功能開發中&#xff0c;已經成功將deepseekAPI接口接入到springbootvue項目中&#xff0c;所以下一步的操作是將對話和消息記錄保存到數據庫中 在之前的開發日志中提到數據庫建表&#xff0c;所以在此刻需要用到兩個表&#xff0c;conversation表和message表&#xff…