Spring Boot配置文件優先級全解析:如何優雅覆蓋默認配置?

📚 一、為什么需要了解配置文件優先級?

想象一下,你正在玩一個游戲🎮,游戲里有默認設置,但你可以通過不同的方式修改這些設置:

  1. 游戲內置的默認設置(就像Spring Boot的默認配置)
  2. 全局配置文件(就像游戲的設置菜單)
  3. 特定場景的特殊設置(就像某個關卡的特殊規則)

Spring Boot的配置文件也是這樣層層疊加的!理解它們的優先級,你就能像游戲高手一樣精準控制應用的行為了!😎

🎯 二、Spring Boot配置文件全家福

Spring Boot支持多種格式的配置文件,主要有:

  1. .properties文件(傳統格式)

    server.port=8080
    
  2. .yml.yaml文件(更簡潔的格式)

    server:port: 8080
    
  3. 環境變量

  4. 命令行參數

這些配置可以同時存在,那Spring Boot怎么決定用哪個呢?這就是優先級的奧秘啦!🔍

🏆 三、配置文件優先級完整排行榜

來啦來啦!最關鍵的優先級排行榜!從高到低依次是:

  1. 命令行參數 👑王者級別

    java -jar myapp.jar --server.port=9090
    
  2. 來自java:comp/env的JNDI屬性 (不太常用)

  3. Java系統屬性(System.getProperties())

    java -Dserver.port=9090 -jar myapp.jar
    
  4. 操作系統環境變量 💻

    export SERVER_PORT=9090
    
  5. 僅在打包的jar外部的特定profile的應用配置文件

    • application-{profile}.propertiesapplication-{profile}.yml
    • 放在jar包同目錄下的config子目錄中
  6. 僅在打包的jar外部的特定profile的應用配置文件

    • 直接放在jar包同目錄下
  7. 打包在jar內的特定profile的應用配置文件

    • 也就是resources目錄下的application-{profile}.propertiesyml
  8. 打包的jar外部的應用配置文件

    • application.propertiesapplication.yml
    • 放在jar包同目錄下的config子目錄中
  9. 打包的jar外部的應用配置文件

    • 直接放在jar包同目錄下
  10. 打包在jar內的應用配置文件

    • 也就是resources目錄下的application.propertiesyml
  11. @Configuration類上的@PropertySource注解 🏷?

    @PropertySource("classpath:custom.properties")
    
  12. SpringApplication.setDefaultProperties設置的默認屬性

哇!是不是有點多?別擔心,我們慢慢來分解理解~ 😊

🧩 四、實際應用場景解析

場景1:開發環境 vs 生產環境

假設我們有一個數據庫配置:

  1. 默認配置 (application.yml)

    spring:datasource:url: jdbc:mysql://localhost:3306/dev_dbusername: dev_userpassword: dev_pass
    
  2. 生產環境配置 (application-prod.yml)

    spring:datasource:url: jdbc:mysql://prod-server:3306/prod_dbusername: prod_userpassword: ${DB_PASSWORD}  # 從環境變量獲取
    

啟動時使用:

java -jar app.jar --spring.profiles.active=prod

這樣,生產環境就會自動使用生產配置啦!🎉

場景2:臨時覆蓋配置

有時候我們需要臨時修改某個配置,比如端口號:

java -jar app.jar --server.port=9090

這樣命令行參數會覆蓋所有文件中的配置,超級方便!?

🔍 五、深度解析:屬性覆蓋機制

Spring Boot使用一個叫PropertySource的抽象概念來管理這些配置。當需要獲取一個屬性值時,它會按照優先級順序查找,找到第一個匹配的就停止。

舉個🌰:

  1. 假設在application.yml中:

    server:port: 8080
    
  2. 同時在環境變量中設置了:

    export SERVER_PORT=9090
    
  3. 啟動命令:

    java -jar app.jar --server.port=7070
    

最終端口會是哪個呢?沒錯,是7070!因為命令行參數優先級最高!🏆

🛠? 六、如何正確覆蓋配置:最佳實踐

1. 多環境配置

推薦使用profile機制:

# application.yml
spring:profiles:active: dev  # 默認使用dev環境# application-dev.yml (開發環境)
server:port: 8080# application-prod.yml (生產環境)
server:port: 80

啟動時指定profile:

java -jar app.jar --spring.profiles.active=prod

2. 敏感信息處理

千萬不要把密碼等敏感信息直接寫在配置文件中!🙅?♂?

推薦做法:

spring:datasource:password: ${DB_PASSWORD}

然后通過環境變量設置:

export DB_PASSWORD=mysecretpassword

3. 外部化配置

把配置文件放在jar包外面,方便修改:

.
├── app.jar
├── config
│   └── application.yml
└── application.yml

這樣修改配置不需要重新打包!👍

💡 七、高級技巧:自定義屬性源

如果你想玩點高級的,可以實現自己的PropertySource

public class CustomPropertySource extends PropertySource {public CustomPropertySource() {super("customPropertySource");}@Overridepublic Object getProperty(String name) {if ("custom.property".equals(name)) {return "我是自定義屬性值";}return null;}
}

然后在配置類中注冊:

@Configuration
public class AppConfig {@Autowiredprivate ConfigurableEnvironment env;@PostConstructpublic void init() {env.getPropertySources().addAfter(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME,new CustomPropertySource());}
}

這樣你就可以用@Value("${custom.property}")獲取自定義屬性啦!🎩?

🧪 八、調試技巧:查看實際生效的配置

想知道最終生效的配置是什么?有幾種方法:

  1. Actuator端點 (如果引入了actuator)

    http://localhost:8080/actuator/env
    
  2. 啟動時打印
    application.yml中添加:

    logging:level:org.springframework.boot.context.properties: DEBUG
    
  3. 編程方式獲取

    @Autowired
    private Environment env;public void someMethod() {String port = env.getProperty("server.port");System.out.println("實際端口: " + port);
    }
    

🚨 九、常見問題與解決方案

Q1: 我的配置修改了為什么不生效?

A: 按照以下步驟檢查:

  1. 確認修改的文件在優先級更高的位置
  2. 檢查是否有拼寫錯誤
  3. 確認沒有更高優先級的配置覆蓋了它
  4. 檢查profile是否激活正確

Q2: yml和properties文件哪個優先級高?

A: 如果同名,.properties優先級高于.yml。但最好統一使用一種格式。

Q3: 如何禁用某個配置文件的加載?

A: 使用:

java -jar app.jar --spring.config.location=optional:file:/path/to/config/

Q4: 配置屬性名中的橫線(-)和下劃線(_)有什么區別?

A: Spring Boot會自動將my.property-namemy.property_name視為相同屬性,方便使用。

🌈 十、實戰演練:完整示例

讓我們通過一個完整例子鞏固所學:

  1. 項目結構

    src/main/resources/application.yml          # 默認配置application-dev.yml      # 開發環境application-prod.yml     # 生產環境
    target/myapp.jar
    config/application.yml              # 外部覆蓋配置
    
  2. application.yml

    spring:profiles:active: dev
    app:name: MyAppversion: 1.0.0
    
  3. application-dev.yml

    server:port: 8080
    db:url: jdbc:mysql://localhost:3306/dev
    
  4. application-prod.yml

    server:port: 80
    db:url: jdbc:mysql://prod-server:3306/prod
    
  5. config/application.yml (外部配置)

    app:version: 1.0.1  # 覆蓋版本號
    
  6. 啟動命令

    java -jar myapp.jar --spring.profiles.active=prod --server.port=9090
    
  7. 最終生效的配置

    • server.port: 9090 (命令行參數最高)
    • app.name: MyApp (默認配置)
    • app.version: 1.0.1 (外部配置覆蓋)
    • db.url: jdbc:mysql://prod-server:3306/prod (prod profile)

完美!現在你完全掌握了配置覆蓋的藝術!🎨

📝 十一、總結:配置優先級核心要點

讓我們用一張表格總結關鍵點:

優先級配置來源示例適用場景
最高命令行參數--server.port=9090臨時測試、運維調整
環境變量export SERVER_PORT=9090容器部署、敏感信息
外部配置文件/config/application.yml生產環境配置
jar內配置文件resources/application.yml默認配置、開發環境
最低默認屬性SpringApplication.setDefaultProperties框架默認值

記住這個口訣:“命環外jar默認”(命令行>環境變量>外部文件>jar內文件>默認)!🗣?

🎁 十二、Bonus:Spring Boot 2.4+配置新特性

如果你使用Spring Boot 2.4及以上版本,還有一些新玩法:

  1. 配置文件分組

    spring:profiles:group:production: db,redis
    

    啟動production相當于同時激活db和redis profile

  2. 導入額外配置

    spring:config:import: optional:file:/path/to/config/
    
  3. 多文檔YAML文件
    可以在一個yml文件中用---分隔多個profile配置

🚀 十三、舉一反三:其他相關知識點

理解了配置優先級,這些相關概念也更容易掌握:

  1. @Value注解:直接從環境獲取屬性值

    @Value("${server.port}")
    private int port;
    
  2. @ConfigurationProperties:類型安全的配置綁定

    @ConfigurationProperties(prefix = "app")
    public class AppProperties {private String name;private String version;// getters/setters
    }
    
  3. Spring Cloud Config:集中式配置管理

📖 十四、延伸閱讀推薦

想更深入學習的同學可以參考:

  1. Spring Boot官方文檔 - 外部化配置
  2. 《Spring Boot實戰》 - 第3章 自定義配置
  3. 《Spring微服務實戰》 - 配置管理章節

🎉 十五、結語

恭喜你!🎊 現在你已經完全掌握了Spring Boot配置文件優先級的精髓!記住:

  • 理解優先級層次是關鍵 🔑
  • 合理使用profile管理多環境 🌎
  • 敏感信息用環境變量保護 🔒
  • 外部化配置讓運維更靈活 🛠?

如果有任何問題,歡迎在評論區留言討論哦!😊 我們下次再見!👋

Happy Coding! 💻?

推薦閱讀文章

  • 由 Spring 靜態注入引發的一個線上T0級別事故(真的以后得避坑)

  • 如何理解 HTTP 是無狀態的,以及它與 Cookie 和 Session 之間的聯系

  • HTTP、HTTPS、Cookie 和 Session 之間的關系

  • 什么是 Cookie?簡單介紹與使用方法

  • 什么是 Session?如何應用?

  • 使用 Spring 框架構建 MVC 應用程序:初學者教程

  • 有缺陷的 Java 代碼:Java 開發人員最常犯的 10 大錯誤

  • 如何理解應用 Java 多線程與并發編程?

  • 把握Java泛型的藝術:協變、逆變與不可變性一網打盡

  • Java Spring 中常用的 @PostConstruct 注解使用總結

  • 如何理解線程安全這個概念?

  • 理解 Java 橋接方法

  • Spring 整合嵌入式 Tomcat 容器

  • Tomcat 如何加載 SpringMVC 組件

  • “在什么情況下類需要實現 Serializable,什么情況下又不需要(一)?”

  • “避免序列化災難:掌握實現 Serializable 的真相!(二)”

  • 如何自定義一個自己的 Spring Boot Starter 組件(從入門到實踐)

  • 解密 Redis:如何通過 IO 多路復用征服高并發挑戰!

  • 線程 vs 虛擬線程:深入理解及區別

  • 深度解讀 JDK 8、JDK 11、JDK 17 和 JDK 21 的區別

  • 10大程序員提升代碼優雅度的必殺技,瞬間讓你成為團隊寵兒!

  • “打破重復代碼的魔咒:使用 Function 接口在 Java 8 中實現優雅重構!”

  • Java 中消除 If-else 技巧總結

  • 線程池的核心參數配置(僅供參考)

  • 【人工智能】聊聊Transformer,深度學習的一股清流(13)

  • Java 枚舉的幾個常用技巧,你可以試著用用

  • 由 Spring 靜態注入引發的一個線上T0級別事故(真的以后得避坑)

  • 如何理解 HTTP 是無狀態的,以及它與 Cookie 和 Session 之間的聯系

  • HTTP、HTTPS、Cookie 和 Session 之間的關系

  • 使用 Spring 框架構建 MVC 應用程序:初學者教程

  • 有缺陷的 Java 代碼:Java 開發人員最常犯的 10 大錯誤

  • Java Spring 中常用的 @PostConstruct 注解使用總結

  • 線程 vs 虛擬線程:深入理解及區別

  • 深度解讀 JDK 8、JDK 11、JDK 17 和 JDK 21 的區別

  • 10大程序員提升代碼優雅度的必殺技,瞬間讓你成為團隊寵兒!

  • 探索 Lombok 的 @Builder 和 @SuperBuilder:避坑指南(一)

  • 為什么用了 @Builder 反而報錯?深入理解 Lombok 的“暗坑”與解決方案(二)

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

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

相關文章

汽車行駛工況特征參數:從“速度曲線”到“駕駛DNA”的硬核解碼

作為新能源汽車行業的從業者,你是否曾困惑于這些問題: 為什么同一款電動車,不同用戶的實際續航差異高達30%?如何精準量化駕駛行為對電池壽命的影響?車企標定的“NEDC續航”與真實路況差距的根源是什么? 這…

HTTP 2.0 協議特性詳解

1. 使用二進制協議,簡化傳輸的復雜性,提高了效率 2. 支持一個 TCP 鏈接發起多請求,移除 pipeline HTTP/2 移除了 HTTP/1.1中的管道化(pipeline)機制,轉而采用多路復用(Multiplexing&#xff0…

完美解決瀏覽器不能復制的問題(比如賽氪網的中題庫練習題)

僅供復制題庫題目進行打印學習使用! 最近想把賽氪網題庫中的題目打印出來做練習,發現題庫中的題目不能復制,不能在試卷上勾畫標記太難受了,而且不能留作材料以后復習,故出此策。 而且CtrlP打印出的pdf會缺少題目。(我…

std::set (C++)

std::set 1. 概述定義特點 2. 內部實現3. 性能特征4. 常用 API5. 使用示例6. 自定義比較器7. 注意事項與優化8. 使用建議 1. 概述 定義 template<class Key,class Compare std::less<Key>,class Allocator std::allocator<Key> > class std::set;特點 有…

SSM省市區三級聯動和三表聯查附帶數據庫

SSM省市區三級聯動和三表聯查 ------附帶數據庫碼云地址&#xff1a;https://gitee.com/Mr_ZKC/NO1 數據庫在項目中

曲棍球·棒球1號位

中國女子曲棍球隊曾涌現過馬弋博、李紅俠等優秀選手&#xff0c;但“李紅”這一名字可能為信息誤差。以下為您系統介紹曲棍球&#xff0c;并結合棒球進行對比分析&#xff1a; 曲棍球&#xff08;Hockey&#xff09;核心特點 運動形式 分為草地曲棍球&#xff08;夏季奧運會項…

12芯束裝光纖不同包層線顏色之間的排列順序

為什么光纖線必須按照以下顏色順序進行排序&#xff1f;這其實是為了防止光污染的問題&#xff0c;不同顏色在傳遞光時從包層表皮漏光傳感到梳妝的其它纖芯上&#xff0c;會有光污染的問題&#xff0c;而為了減少并防止光污染的現象&#xff0c;所以在光通信之中&#xff0c;需…

c++程序的打包編譯cmake+make

c打包編譯 1 在不用系統中打包介紹1.1 linux中打包c程序的2種方式1.2 windows中打包c程序1.3 cmakeNinja和cmakemake的兩種方式對比1.3.1 Ninja是什么&#xff08;可以認為是make工具的一個替代產品&#xff09;1.3.2 cmakeNinja可以用于linux和windows系統中&#xff0c;編譯效…

Spark on K8s 在 vivo 大數據平臺的混部實戰與優化

一、Spark on K8s 簡介 (一)定義與架構 Spark on K8s 是一種將 Spark 運行在 Kubernetes(K8s)集群上的架構,由 K8s 直接創建 Driver 和 Executor 的 Pod 來運行 Spark 作業。其架構如下。 Driver Pod:相當于 Spark 集群中的 Driver,負責作業的調度和管理,它會根據作業…

MDA測量數據查看器【內含工具和源碼地址】

一、工具介紹 MDA測量數據查看器用于顯示和分析以MDF格式提供的測量數據。 支持MDF3.3之前含MDF3.3的二進制格式&#xff0c;支持Vector CANape and ETAS Inca. Kvaser CAN Logger (MDF 3.2) 文件。 MDF (Measurement Data Format)是一種二進制文件&#xff0c;用來記錄、交換…

番外篇 | SEAM-YOLO:引入SEAM系列注意力機制,提升遮擋小目標的檢測性能

前言:Hello大家好,我是小哥談。SEAM(Squeeze-and-Excitation Attention Module)系列注意力機制是一種高效的特征增強方法,特別適合處理遮擋和小目標檢測問題。該機制通過建模通道間關系來自適應地重新校準通道特征響應。在遮擋小目標檢測中的應用優勢包括:1)通道注意力增強…

使用VHDL語言實現TXT文件的讀寫操作

使用FPGA進行圖像處理時&#xff0c;通常需要將TXT文件中的圖像數據讀出到TestBench中&#xff0c;并將仿真的結果寫入到TXT文件中&#xff0c;用于確認圖像處理的結果是否正確。 VHDL中TXT文件的讀寫操作如下所示&#xff0c; --------------------------------------------…

基于Redis的4種延時隊列實現方式

延時隊列是一種特殊的消息隊列&#xff0c;它允許消息在指定的時間后被消費。在微服務架構、電商系統和任務調度場景中&#xff0c;延時隊列扮演著關鍵角色。例如&#xff0c;訂單超時自動取消、定時提醒、延時支付等都依賴延時隊列實現。 Redis作為高性能的內存數據庫&#x…

GN ninja 工程化構建例程

文章目錄 1. 前言?2. 工程實例??2.1 工程目錄結構2.2 工程頂層.gn文件2.3 工具鏈配置.gn文件2.4 編譯配置.gn文件2.5 編譯目標配置.gn文件2.6 工程接口文件2.7 動態庫編譯.gn文件2.8 動態庫源文件2.9 靜態庫編譯.gn文件2.10 靜態庫源文件2.11 主程序編譯.gn文件2.12 主程序源…

基于亞博K210開發板——內存卡讀寫文件

開發板 亞博K210開發板 實驗目的 本實驗主要學習 K210 通過 SPI 讀寫內存卡文件的功能 實驗準備 實驗元件 開發板自帶的 TF 卡、LCD 顯示屏 &#xff08;提前準備好 FAT32 格式的TF 卡。TF 插入 TF 卡槽的時候注意方向&#xff0c;TF 卡的金手指那一面需要面向開發板&am…

51單片機實驗五:A/D和D/A轉換

一、實驗環境與實驗器材 環境&#xff1a;Keli&#xff0c;STC-ISP燒寫軟件,Proteus. 器材&#xff1a;TX-1C單片機&#xff08;STC89C52RC&#xff09;、電腦。 二、 實驗內容及實驗步驟 1.A/D轉換 概念&#xff1a;模數轉換是將連續的模擬信號轉換為離散的數字信…

C++ 常用的智能指針

C 智能指針 一、智能指針類型概覽 C 標準庫提供以下智能指針&#xff08;需包含頭文件 <memory>&#xff09;&#xff1a; unique_ptr&#xff1a;獨占所有權&#xff0c;不可復制&#xff0c; 可移動shared_ptr&#xff1a;共享所有權&#xff0c;用于引用計數weak_pt…

6.8.最小生成樹

一.復習&#xff1a; 1.生成樹&#xff1a; 對于一個連通的無向圖&#xff0c;假設圖中有n個頂點&#xff0c;如果能找到一個符合以下要求的子圖&#xff1a; 子圖中包含圖中所有的頂點&#xff0c;同時各個頂點保持連通&#xff0c; 而且子圖的邊的數量只有n-1條&#xff0…

Spring Boot 集成金蝶 API 演示

? Spring Boot 集成金蝶 API 演示&#xff1a;登錄 / 注銷 Cookie 保存 本文將通過 Spring Boot 完整實現一套金蝶接口集成模型&#xff0c;包括&#xff1a; ? 普通登錄? AppSecret 登錄? 注銷? Cookie 保存與復用 &#x1f4c5; 項目結構 src/ ├── controller/ │…