Springboot載入配置檔案

胡一省發表於2019-04-28

本文主要集中測試和探討一下 SpringBoot 的配置檔案載入機制。

一個簡單的SpringBoot工程,工程目錄結構如下:

Springboot載入配置檔案

Springboot載入配置檔案

實現功能:

通過訪問 "/person" 這個介面,返回 PersonConfig 配置物件中的name和age屬性。

resource目錄下的 yml 檔案配置如下:

Springboot載入配置檔案

先將其打成 jar 包執行。

這裡要說一下給Springboot工程打jar包的方法。

只需要簡單地,在pom檔案中的build屬性新增下面的配置項即可,無需自己再新增 shade 或者 assembly 指定 mainClass 打包(關於這個實現機制,在後面的文章會集中探討。)。

			<plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.1.4.RELEASE</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
複製程式碼

執行命令,執行該 jar 包。

java -jar springboot-test-1.0-SNAPSHOT.jar
複製程式碼

呼叫介面,檢視返回結果。

Springboot載入配置檔案
這裡的執行我們並沒有指定配置yml檔案路徑。反編譯 jar 包後檢視可知 yml 檔案已經和所有的class檔案一起打包在jar包裡了。

Springboot載入配置檔案

但是在生產環境中,我們往往需要的是實現可配置。這時候我們可以使用 springboot 提供的一個叫 Externalized Configuration 機制。

參考 springboot 官方文件相關說明如下:

Spring Boot lets you externalize your configuration so that you can work with the same application code in different environments. You can use properties files, YAML files, environment variables, and command-line arguments to externalize configuration. Property values can be injected directly into your beans by using the @Value annotation, accessed through Spring’s Environment abstraction, or be bound to structured objects through @ConfigurationProperties.

這段話主要提到了 springboot 的四種配置機制:property 檔案,yml 檔案,環境變數,命令列。其實細看後面的說明,文件中提到了 17 種配置方式,但是鑑於常用的的方式主要有這四種,所以以下就這四種機制進行探討。

YAML 檔案配置方式

jar包同級的 yaml 檔案

我們在jar包同級目錄下放置 yml 配置檔案,配置項如下所示:

Springboot載入配置檔案

通過命令列引數指定yml檔案路徑,執行如下所示的命令:

java -jar springboot-test-1.0-SNAPSHOT.jar 
--spring.config.location=file:./application.yml
複製程式碼

執行結果:

Springboot載入配置檔案
可以看到jar包內yml檔案中的屬性已經被覆蓋了。

如果此時不在命令列引數中指定結果會怎樣,程式會載入jar外的配置檔案還是jar包內部的?

執行下面的指令:

java -jar springboot-test-1.0-SNAPSHOT.jar
複製程式碼

執行結果:

Springboot載入配置檔案

可以看出來,結果與上面相同,即springboot會優先載入jar包外的 yml 檔案,並提取其中引數配置項的值覆蓋 jar包內的 yml 檔案。

如果我們把jar外的yml檔案刪除,會怎樣?

Springboot載入配置檔案
可以看到,此時的值已經成為jar包內配置的了。

但是,如果用命令列指定配置檔案的路徑,那麼所有的配置檔案路徑都可以麼?對此 springboot 是有規範的。

Springboot載入配置檔案
只有以上四種情況。

下面我們把 yml 檔案放到一個叫 other 的資料夾下,並通過命令列引數指定檔案路徑執行。

java -jar springboot-test-1.0-SNAPSHOT.jar  
--spring.config.location=file:./other/application.yml
複製程式碼

此時的執行結果:

Springboot載入配置檔案
可知命令列指定的配置檔案並沒有起作用。驗證了上面提到的四種路徑規範。

而且這些路徑之間的優先順序如下:

1.file:./config/
2.file:./
3.classpath:/config/
4.classpath:/
複製程式碼

springboot 掃描配置檔案的順序從1到4。只要掃描到了配置檔案,則不再繼續掃描。

現在我們在 config 目錄下和 jar 包同級根目錄下同時放置 yml 配置檔案。

Springboot載入配置檔案
jar 包同級目錄下放置 yml 配置如上圖所示。執行命令:

java -jar springboot-test-1.0-SNAPSHOT.jar 
複製程式碼

執行結果:

Springboot載入配置檔案
可知結果符合上面描述的優先順序。

相關文章