Post-Processing PropertySource instance詳解 和 BeanFactoryPostProcessor詳解

PropertySourcesBeanFactoryPostProcessor詳解

在這里插入圖片描述


1. 核心概念

BeanFactoryPostProcessor 是 Spring 框架中用于在 BeanFactory 初始化階段Environment 中的 PropertySource 進行后處理的接口。它允許開發者在 Bean 創建之前 對屬性源進行動態修改,例如添加、刪除或轉換屬性。


2. 核心流程與類關系
2.1 核心接口與實現
  • 接口定義

    public interface PropertySourcesBeanFactoryPostProcessor {void postProcessPropertySources(ConfigurableListableBeanFactory beanFactory, MutablePropertySources propertySources);
    }
    
    • 參數
      • ConfigurableListableBeanFactory:Spring 的 BeanFactory 實例。
      • MutablePropertySources:可修改的屬性源集合(包含所有已加載的 PropertySource)。
  • 作用
    在 BeanFactory 初始化過程中,提供對 PropertySource 的直接修改能力,例如:

    • 動態添加自定義屬性源(如從數據庫讀取配置)。
    • 過濾敏感屬性(如密碼)。
    • 調整屬性源的優先級。

3. 典型使用場景
3.1 動態添加 PropertySource
// 示例:從數據庫加載配置并添加到 PropertySources
public class DatabasePropertySourcePostProcessor implements PropertySourcesBeanFactoryPostProcessor {@Overridepublic void postProcessPropertySources(ConfigurableListableBeanFactory beanFactory, MutablePropertySources propertySources) {// 1. 從數據庫獲取配置Map<String, Object> dbProps = loadConfigFromDatabase();// 2. 創建自定義 PropertySourcePropertySource<?> dbPropertySource = new MapPropertySource("databaseConfig", dbProps);// 3. 將其添加到最高優先級(覆蓋現有配置)propertySources.addFirst(dbPropertySource);}
}
3.2 過濾敏感屬性
public class SensitivePropertyFilter implements PropertySourcesBeanFactoryPostProcessor {@Overridepublic void postProcessPropertySources(ConfigurableListableBeanFactory beanFactory, MutablePropertySources propertySources) {// 遍歷所有 PropertySource 并過濾敏感鍵List<PropertySource<?>> filteredSources = new ArrayList<>();for (PropertySource<?> source : propertySources) {if (source instanceof EnumerablePropertySource) {Map<String, Object> filteredProps = new HashMap<>();for (String key : ((EnumerablePropertySource<?>) source).getPropertyNames()) {if (!key.contains("password")) {filteredProps.put(key, source.getProperty(key));}}PropertySource<?> filteredSource = new MapPropertySource(source.getName(), filteredProps);filteredSources.add(filteredSource);}}// 替換原有的 PropertySourcespropertySources.clear();propertySources.addAll(filteredSources);}
}
3.3 調整屬性源優先級
public class CustomPropertyOrderPostProcessor implements PropertySourcesBeanFactoryPostProcessor {@Overridepublic void postProcessPropertySources(ConfigurableListableBeanFactory beanFactory, MutablePropertySources propertySources) {// 將某個 PropertySource 移動到最高優先級PropertySource<?> sourceToMove = propertySources.get("customConfig");if (sourceToMove != null) {propertySources.remove("customConfig");propertySources.addFirst(sourceToMove);}}
}

4. 實現步驟
4.1 定義處理器
public class CustomPropertyProcessor implements PropertySourcesBeanFactoryPostProcessor {@Overridepublic void postProcessPropertySources(ConfigurableListableBeanFactory beanFactory, MutablePropertySources propertySources) {// 在此處實現屬性源的修改邏輯}
}
4.2 注冊處理器

通過 @Bean 注冊到 Spring 容器:

@Configuration
public class AppConfig {@Beanpublic PropertySourcesBeanFactoryPostProcessor customProcessor() {return new CustomPropertyProcessor();}
}
4.3 集成到 Spring Boot

在 Spring Boot 中,可以通過 EnvironmentPostProcessor 在啟動時注入:

public class CustomEnvironmentPostProcessor implements EnvironmentPostProcessor {@Overridepublic void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {// 在此處注冊 PropertySourcesBeanFactoryPostProcessor}
}

5. 關鍵流程與方法
5.1 屬性源處理流程
Spring Boot 啟動 →加載所有 PropertySource(如 application.properties、環境變量等) →調用 PropertySourcesBeanFactoryPostProcessor.postProcessPropertySources() →修改后的 PropertySources 用于后續 Bean 的屬性注入。
5.2 核心方法詳解
方法說明
postProcessPropertySources()核心方法,接收 BeanFactoryMutablePropertySources,進行屬性源修改。
propertySources.addFirst(source)將屬性源添加到最高優先級(覆蓋現有配置)。
propertySources.remove(name)移除指定名稱的屬性源。
propertySources.get(name)根據名稱獲取屬性源。

6. 典型應用場景總結
場景解決方案示例代碼片段
動態配置注入從數據庫/遠程服務加載配置并添加為 PropertySource。propertySources.addFirst(new MapPropertySource("dbConfig", dbProps));
敏感信息過濾移除或修改包含敏感信息的屬性鍵(如密碼)。if (!key.contains("password")) { ... }
優先級調整將自定義配置的優先級設為最高,覆蓋默認配置。propertySources.addFirst(existingSource);
屬性值轉換將字符串屬性轉換為復雜類型(如 ListMap)。Map<String, Object> convertedProps = ...

7. 注意事項
  1. 執行時機:在 BeanFactory 初始化階段執行,早于 @PostConstruct 和 Bean 初始化。
  2. 優先級控制:通過 addFirst()addLast()insertBefore()/insertAfter() 精確控制屬性源順序。
  3. 副作用風險:避免在處理器中執行耗時操作,可能影響應用啟動速度。
  4. Spring Boot 集成:需確保處理器在 Environment 初始化后被正確調用。

8. 總結表格
功能實現方式適用場景
動態配置注入通過 addFirst() 添加自定義 PropertySource。需要從外部源(如數據庫)加載配置時。
屬性過濾遍歷 PropertySources 并移除敏感鍵。隱藏敏感配置(如數據庫密碼、API密鑰)。
優先級調整使用 addFirst()remove() 調整屬性源順序。需要高優先級配置覆蓋默認值(如測試環境覆蓋生產配置)。
屬性值轉換在處理器中修改屬性值類型(如字符串轉 List)。需要動態解析復雜類型配置時。

通過 PropertySourcesBeanFactoryPostProcessor,可以靈活控制屬性源的加載和修改邏輯,滿足復雜配置需求。

延伸閱讀

Post-Processing PropertySource instance詳解


1. 核心概念

PropertySource 是 Spring 框架中用于管理配置屬性的抽象類,負責從不同來源(如 application.properties、環境變量、系統屬性等)加載屬性值。
Post-Processing 是指在 PropertySource 被創建或注冊到 Environment 后,對其內容進行進一步的處理或修改。


2. 核心流程與類關系
2.1 核心類與接口
類/接口作用
PropertySource屬性源的抽象基類,封裝屬性鍵值對(如 server.port=8080)。
EnvironmentSpring 的環境對象,管理所有 PropertySource 的優先級和合并邏輯。
PropertySources存儲 PropertySource 集合的容器,按優先級排序。
PropertySourceProcessorPropertySource 進行后處理的接口(如過濾、轉換屬性)。
PropertySourcesPropertyResolver根據優先級從多個 PropertySource 中解析屬性值的工具類。
2.2 核心流程
  1. 屬性源加載:Spring Boot 啟動時,從 application.properties、YAML 文件、環境變量等加載屬性,生成多個 PropertySource 實例。
  2. 屬性源注冊:將所有 PropertySource 注冊到 EnvironmentPropertySources 容器中。
  3. 后處理階段:對已注冊的 PropertySource 進行統一處理(如過濾敏感屬性、替換占位符、合并配置等)。

3. 典型 Post-Processing 場景
3.1 屬性過濾
  • 場景:隱藏敏感屬性(如密碼、API密鑰)。
  • 實現方式
    // 自定義 PropertySourceProcessor
    public class SensitivePropertyFilter implements PropertySourceProcessor {@Overridepublic PropertySource<?> processPropertySource(PropertySource<?> source) {if (source.getName().equals("someConfig")) {Map<String, Object> filteredProps = new HashMap<>();((MapPropertySource) source).forEach((key, value) -> {if (!key.contains("password")) {filteredProps.put(key, value);}});return new MapPropertySource(source.getName(), filteredProps);}return source;}
    }
    
3.2 屬性值轉換
  • 場景:將字符串屬性轉換為其他類型(如 ListMap)。
  • 實現方式
    public class TypeConverterProcessor implements PropertySourceProcessor {@Overridepublic PropertySource<?> processPropertySource(PropertySource<?> source) {Map<String, Object> convertedProps = new HashMap<>();((MapPropertySource) source).forEach((key, value) -> {if (key.endsWith(".asList")) {convertedProps.put(key, Arrays.asList(value.toString().split(",")));} else {convertedProps.put(key, value);}});return new MapPropertySource(source.getName(), convertedProps);}
    }
    
3.3 屬性覆蓋與合并
  • 場景:根據優先級合并多個屬性源(如 application.properties 覆蓋默認配置)。
  • 實現方式
    // Spring 的默認合并邏輯由 PropertySourcesPropertyResolver 處理
    Environment env = ...;
    String value = env.getProperty("key"); // 自動按優先級合并
    

4. 自定義 Post-Processing 的實現步驟
4.1 實現 PropertySourceProcessor
public class CustomPropertyProcessor implements PropertySourceProcessor {@Overridepublic PropertySource<?> processPropertySource(PropertySource<?> source) {// 在此處修改或過濾 PropertySourcereturn source; // 返回修改后的 PropertySource}
}
4.2 注冊處理器
@Configuration
public class PropertyConfig {@Beanpublic PropertySourceProcessor customProcessor() {return new CustomPropertyProcessor();}
}
4.3 集成到 Spring Boot

通過 EnvironmentPostProcessor 在啟動時注入處理器:

public class CustomEnvironmentPostProcessor implements EnvironmentPostProcessor {@Overridepublic void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {environment.getPropertySources().addFirst(new CustomPropertySourceProcessor().processPropertySource(...));}
}

5. 關鍵方法與流程
5.1 屬性解析流程
Environment.getProperty(key) →PropertySourcesPropertyResolver →遍歷 PropertySources(按優先級) →調用 PropertySource.getProperty(key) →返回第一個非空值
5.2 核心方法詳解
方法作用
PropertySource.getProperty(key)根據鍵直接從當前屬性源獲取值。
PropertySources.getFirst(name)根據名稱獲取第一個匹配的屬性源。
PropertySources.addFirst(source)將屬性源添加到優先級最高位置(覆蓋現有配置)。

6. 典型應用場景
場景解決方案
敏感屬性過濾實現 PropertySourceProcessor 過濾敏感鍵(如 password)。
動態屬性注入EnvironmentPostProcessor 中動態添加屬性源(如從數據庫讀取配置)。
屬性值類型轉換使用 PropertySourceProcessor 將字符串轉換為復雜類型(如 ListMap)。
多環境配置合并按優先級加載 application-{profile}.properties 并合并到 Environment。

7. 總結表格
功能實現方式適用場景
屬性過濾實現 PropertySourceProcessor 過濾敏感鍵。隱藏敏感配置(如數據庫密碼)。
屬性轉換在處理器中修改屬性值類型(如字符串轉 List)。需要動態解析復雜類型配置時。
屬性覆蓋通過 PropertySources.addFirst() 調整屬性源優先級。需要高優先級配置覆蓋默認值(如測試環境覆蓋生產配置)。
動態屬性注入EnvironmentPostProcessor 中注冊新 PropertySource。配置需從外部源(如數據庫、API)動態加載時。

8. 注意事項
  1. 優先級控制:屬性源的加載順序決定了覆蓋規則,需通過 PropertySources.addFirst()addLast() 明確優先級。
  2. 性能影響:復雜的后處理邏輯可能增加啟動時間,需避免在高頻路徑中執行。
  3. Spring Boot 集成:通過 @ConfigurationEnvironmentPostProcessor 靈活擴展。

通過以上方法,可以靈活控制屬性源的后處理邏輯,滿足復雜配置需求。

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

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

相關文章

[C]基礎13.深入理解指針(5)

博客主頁&#xff1a;向不悔本篇專欄&#xff1a;[C]您的支持&#xff0c;是我的創作動力。 文章目錄 0、總結1、sizeof和strlen的對比1.1 sizeof1.2 strlen1.3 sizeof和strlen的對比 2、數組和指針筆試題解析2.1 一維數組2.2 字符數組2.2.1 代碼12.2.2 代碼22.2.3 代碼32.2.4 …

賽靈思 XCKU115-2FLVB2104I Xilinx Kintex UltraScale FPGA

XCKU115-2FLVB2104I 是 AMD Xilinx Kintex UltraScale FPGA&#xff0c;基于 20 nm 先進工藝&#xff0c;提供高達 1 451 100 個邏輯單元&#xff08;Logic Cells&#xff09;&#xff0c;77 721 600 bit 的片上 RAM 資源&#xff0c;以及 5 520 個 DSP 切片&#xff08;DSP48E…

CAPL編程_03

1_文件操作的相關函數&#xff1a; 讀文本文件內容 讀取文本文件操作的三部曲 1&#xff09;打開文件 —— openFileRead ( ) 2&#xff09;逐行讀取 —— fileGetString ( ) 、fileGetStringSZ ( ) 3&#xff09;關閉文件 —— fileClose ( ) char content[100];…

2025年江西建筑安全員A證適合報考人群

江西建筑安全員A證適合報考人群 江西省建筑安全員A證&#xff08;建筑施工企業主要負責人安全生產考核合格證書&#xff09;主要面向建筑行業管理人員&#xff0c;適合以下人員報考&#xff1a; 1. 企業主要負責人 法人代表、總經理、分管安全副總&#xff1a;依法需持A證&a…

Docker安裝(Ubuntu22版)

前言 你是否還在為Linux上配置Docker而感到煩惱&#xff1f; 你是否還在為docker search&#xff0c;docker pull連接不上&#xff0c;而感到沮喪&#xff1f; 本文將解決以上你的所有煩惱&#xff01;快速安裝好docker&#xff01; Docker安裝 首先&#xff0c;我們得先卸載…

Ubuntu18.04配置C++環境和Qt環境

Ubuntu18.04配置C環境和Qt環境 1、前言3.2 安裝其他庫3.3 查看有沒有安裝成功3.4測試C環境 4、配置Qt環境4.1 安裝相關的庫4.2 測試 5、總結 1、前言 記錄一下Ubuntu18.04配置C環境和Qt環境的過程&#xff0c;方便自己日后回顧&#xff0c;也可以給有需要的人提供幫助。 # 2…

ACWing——算法基礎課

置頂思考&#xff1a; 算法的本質是什么樣的思想&#xff1f; 這種思想可以解決哪類問題&#xff1f; 有沒有其他的解決思路&#xff1f; 關注數值范圍&#xff0c;思考可不可以針對性解決問題&#xff1f; 目錄 https://leetcode.cn/circle/discuss/RvFUtj/ 滑動窗口與雙指針…

私鑰連接服務器(已經有服務器私鑰

前言&#xff1a;假設我們已經有了服務器的私鑰&#xff0c;我們怎么配置呢&#xff1f; 下面我會從vsc的配置角度來寫 ? 步驟一&#xff1a;準備工作 安裝 VS Code&#xff08;如果還沒裝&#xff09; &#x1f449; https://code.visualstudio.com/ 安裝插件&#xff1a;Re…

Redis LFU 策略參數配置指南

一、基礎配置步驟? 設置內存上限? 在 redis.conf 配置文件中添加以下指令&#xff0c;限制 Redis 最大內存使用量&#xff08;例如設置為 4GB&#xff09;&#xff1a; maxmemory 4gb選擇 LFU 淘汰策略? 根據鍵的作用域選擇策略&#xff1a; # 所有鍵參與淘汰 maxmemory-…

嵌入式 C 語言面試核心知識點全面解析:基礎語法、運算符與實戰技巧

在嵌入式面試中&#xff0c;C 語言基礎是重中之重。本文針對經典面試題進行詳細解析&#xff0c;幫助新手系統掌握知識點&#xff0c;提升面試應對能力。 一、數據結構邏輯分類 題目 在數據結構中&#xff0c;從邏輯上可以把數據結構分為&#xff08; &#xff09;。 A、動態…

11.AOP開發

十一、AOP開發 1、Spring Boot實現 AOP 11.1.1、SpringBootAop簡介 Spring Boot的AOP編程和Spring框架中AOP編程的唯一區別是&#xff1a;引入依賴的方式不同,其他內容完全一樣 Spring Boot中AOP編程需要引入aop啟動器&#xff1a; <!--aop啟動器--> <dependency…

【網絡入侵檢測】基于源碼分析Suricata的PCAP模式

【作者主頁】只道當時是尋常 【專欄介紹】Suricata入侵檢測。專注網絡、主機安全,歡迎關注與評論。 1. 概要 ?? 本文聚焦于 Suricata 7.0.10 版本源碼,深入剖析其 PCAP 模式的實現原理。通過系統性拆解初始化階段的配置流程、PCAP 數據包接收線程的創建與運行機制,以及數據…

.NET 10 中的新增功能

.NET 運行時 .NET 10 運行時引入了新功能和性能改進。 關鍵更新包括&#xff1a; 數組接口方法反虛擬化&#xff1a;JIT 現在可以取消虛擬化和內聯數組接口方法&#xff0c;從而提高數組枚舉的性能。數組枚舉去抽象化&#xff1a;改進功能以通過枚舉器減少數組迭代的抽象開銷…

盲注命令執行(Blind Command Execution)

一、核心原理 1. 無回顯命令執行的本質 盲命令執行&#xff08;Blind Command Execution&#xff09;是一種攻擊形式&#xff0c;攻擊者通過注入系統命令到Web應用或后端系統中&#xff0c;但無法直接獲取命令執行結果。盲命令執行的本質在于攻擊者無法直接看到執行結果&#x…

Linux多線程技術

什么是線程 在一個程序里的多執行路線就是線程。線程是進程中的最小執行單元&#xff0c;可理解為 “進程內的一條執行流水線”。 進程和線程的區別 進程是資源分配的基本單位&#xff0c;線程是CPU調度的基本單位。 fork創建出一個新的進程&#xff0c;會創建出一個新的拷貝&…

計算機組成原理實驗(1) 算術邏輯運算單元實驗

實驗一 算術邏輯運算單元實驗 一、實驗目的 1、掌握簡單運算器的數據傳輸方式 2、掌握74LS181的功能和應用 二、實驗內容 1、不帶進位位邏輯或運算實驗 2、不帶進位位加法運算實驗 3、實驗指導書2.15實驗思考 三、實驗步驟和結果 實驗內容一&#xff1a;不帶進位…

Android將啟動畫面實現遷移到 Android 12 及更高版本

如果在 Android 11 或更低版本中實現自定義啟動畫面&#xff0c;請遷移應用遷移到 SplashScreen API 以獲取幫助 確保其在 Android 12 及更高版本中正確顯示。 從 Android 12 開始&#xff0c;在所有應用的冷啟動和溫啟動期間&#xff0c;系統都會應用 Android 系統的默認啟動…

692. 前K個高頻單詞(map的練習)

目錄 1、題目分析 2.解題思路 3.代碼實現 4.總結 1、題目分析 2.解題思路 首先它給出我們一個string&#xff0c;讓我們提取出它們中出現次數最多的。利用map將word一個一個存入其中&#xff0c;沒有就插入&#xff0c;有了就1&#xff0c;這樣我們就得到了key_value&#…

如何創建極狐GitLab 議題?

極狐GitLab 是 GitLab 在中國的發行版&#xff0c;關于中文參考文檔和資料有&#xff1a; 極狐GitLab 中文文檔極狐GitLab 中文論壇極狐GitLab 官網 創建議題 (BASIC ALL) 創建議題時&#xff0c;系統會提示您輸入議題的字段。 如果您知道要分配給議題的值&#xff0c;則可…

day32 學習筆記

文章目錄 前言一、霍夫變換二、標準霍夫變換三、統計概率霍夫變換四、霍夫圓變換 前言 通過今天的學習&#xff0c;我掌握了霍夫變換的基本原本原理及其在OpenCV中的應用方法 一、霍夫變換 霍夫變換是圖像處理中的常用技術&#xff0c;主要用于檢測圖像中的直線&#xff0c;圓…