1. 程式人生 > >詳解Spring Boot 配置載入順序及屬性載入順序

詳解Spring Boot 配置載入順序及屬性載入順序

先給大家介紹下spring boot 配置載入順序,具體內容如下所示:

使用 Spring Boot 會涉及到各種各樣的配置,如開發、測試、線上就至少 3 套配置資訊了。Spring Boot 可以輕鬆的幫助我們使用相同的程式碼就能使開發、測試、線上環境使用不同的配置。

在 Spring Boot 裡面,可以使用以下幾種方式來載入配置。本章內容基於 Spring Boot 2.0 進行詳解。

1、properties檔案;

2、YAML檔案;

3、系統環境變數;

4、命令列引數;

等等……

我們可以在 Spring Beans 裡面直接使用這些配置檔案中載入的值,如:

1、使用 @Value 註解直接注入對應的值,這能獲取到 Spring 中 Environment 的值;

2、使用 @ConfigurationProperties 註解把對應的值繫結到一個物件;

3、直接獲取注入 Environment 進行獲取;

配置屬性的方式很多,Spring boot使用了一種獨有的 PropertySource 可以很方便的覆蓋屬性的值。

配置屬性載入的順序如下:

1、開發者工具 `Devtools` 全域性配置引數;

2、單元測試上的 `@TestPropertySource` 註解指定的引數;

3、單元測試上的 

`@SpringBootTest` 註解指定的引數;

4、命令列指定的引數,如 `java -jar springboot.jar --name="Java技術棧"`;

5、命令列中的 `SPRING_APPLICATION_JSONJSON` 指定引數, 如 `java -Dspring.application.json='{"name":"Java技術棧"}' -jar springboot.jar`

6、`ServletConfig` 初始化引數;

7、`ServletContext` 初始化引數;

8、JNDI引數(如 `java:comp/env/spring.application.json`);

9、Java系統引數(來源:`System.getProperties()`);

10、作業系統環境變數引數;

11、`RandomValuePropertySource` 隨機數,僅匹配:`ramdom.*`;

12、JAR包外面的配置檔案引數(`application-{profile}.properties(YAML)`)

13、JAR包裡面的配置檔案引數(`application-{profile}.properties(YAML)`)

14、JAR包外面的配置檔案引數(`application.properties(YAML)`)

15、JAR包裡面的配置檔案引數(`application.properties(YAML)`)

16、`@Configuration`配置檔案上 `@PropertySource` 註解載入的引數;

17、預設引數(通過 `SpringApplication.setDefaultProperties` 指定);

數字小的優先順序越高,即數字小的會覆蓋數字大的引數值,我們來實踐下,驗證以上配置引數的載入順序。

1、在主應用程式中新增 Java 系統引數。

?

1

2

3

4

5

6

@Bean

public CommandLineRunner commandLineRunner() {

  return (args) -> {

    System.setProperty("name", "javastack-system-properties");

  };

}

2、在 application.properties 檔案中新增屬性。

?

1

name = javastack-application

3、在 application-dev.properties 檔案中新增屬性。

?

1

name = javastack-application-dev

4、新增測試類

?

1

2

3

4

5

6

7

8

9

10

11

@RunWith(SpringRunner.class)

@SpringBootTest(value = { "name=javastack-test", "sex=1" })

@ActiveProfiles("dev")

public class SpringBootBestPracticeApplicationTests {

  @Value("${name}")

  private String name;

  @Test

  public void test() {

    System.out.println("name is " + name);

  }

}

執行 test 單元測試,程式輸出:

?

1

name is javastack-test

根據以上引數動態調整,發現引數會被正確被覆蓋。瞭解了 Spring Boot 各種配置的載入順序,如果配置被覆蓋了我們就知道是什麼問題了。

下面看下springboot屬性載入順序

優先順序按照順序由高到低,數字越小優先順序越高

1.在命令列中傳入的引數。類似於java -jar -Dspring.profiles.active之類。
2.SPRING_APPLICATION_JSON屬性,該屬性以JSON形式儲存在系統環境變數中。
3.java:comp/env中JNDI屬性。
4.Java的系統的屬性,可通過System.getProperties()獲得相關內容。
5.作業系統中的環境變數。
6.通過random.*配置的隨機屬性。
7.位於當前應用jar包外,針對不同{profile}環境的配置檔案內容。
8.位於當前應用jar包內,針對不同{profile}環境的配置檔案內容。
9.位於當前應用jar包外的application.properties或application.yml配置內容。
10.位於當前應用jar包內的application.properties或application.yml配置內容。
11.在@Configuration註解修改的類中,通過@PropertySource註解定義的屬性。
12.應用預設屬性,使用SpringApplication.setDefaultProperties定義的屬性內容。

注:當發現自己使用springboot時,使用到的屬性與自己希望得到的屬性值由差異時,從以上載入順序中去檢視相關屬性內容。