Spring Boot 配置優先級順序

Spring Boot 項目存在一種優先級配置讀取的機制,後面詳細介紹一下:

外部化的配置

Spring 框架本身提供了多種的方式來管理配置屬性文件。Spring 3.1 之前可以使用 PropertyPlaceholderConfigurer。Spring 3.1 引入了新的環境(Environment)和概要信息(Profile)API,是一種更加靈活的處理不同環境和配置文件的方式。但是 Spring 這些配置管理方式的問題在於選擇太多,有些雜亂。Spring Boot 提供了一種統一的方式來管理應用的配置,允許使用屬性文件、YAML 文件、環境變量和命令行參數來定義優先級不同的配置值。按照優先級從高到低的順序依次爲:

1. 命令行參數[命令行參數的優先級被設置爲最高。這樣的好處是可以在測試或生產環境中快速地修改配置參數值,而不需要重新打包和部署應用]。
2. 通過 System.getProperties() 獲取的 Java 系統參數。
3. 操作系統環境變量。
4. 從 java:comp/env 得到的 JNDI 屬性。
5. 通過 RandomValuePropertySource 生成的“random.*”屬性。
6. 應用 Jar 文件之外的屬性文件。(通過spring.config.location參數)
7. 應用 Jar 文件內部的屬性文件。
8. 在應用配置 Java 類(包含“@Configuration”註解的 Java 類)中通過“@PropertySource”註解聲明的屬性文件。
9. 通過“SpringApplication.setDefaultProperties”聲明的默認屬性。

按照優先級劃分了配置文件的優先級之後,如果Spring Boot在優先級更高的位置找到了配置,那麼它就會無視優先級低的配置。比如:

我在application.properties的目錄中,寫入本地的MySQL的配置:
  db.jdbc.driver=com.mysql.jdbc.Driver
  db.jdbc.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8
  db.jdbc.username=username
  db.jdbc.password=password

在自己項目調試的階段,項目總是會使用本地的MySQL數據庫。而一旦打包之後,在外部聲明一個test_evn.properties.
啓動Jar包的時候, 指定一個外部配置文件:

java -jar demo.jar --spring.config.location=/path/test_evn.properties

這樣一來,我們在開發者的機器上總是使用自己的配置,而一到對應的環境,就會使用高級的位置所做的配置。SpringApplication 類默認會把以“--”開頭的命令行參數轉化成應用中可以使用的配置參數,如 “--name=Alex” 會設置配置參數 “name” 的值爲 “Alex”。如果不需要這個功能,可以通過 “SpringApplication.setAddCommandLineProperties(false)” 禁用解析命令行參數。
在代碼中讀取這些配置也是非常方便的,在代碼的邏輯中,其實是無需去關心這個配置是從什麼地方來的,只用關注能獲取什麼配置就夠了。

程序代碼如下:
public class ApplicationConfigure {
    @Value("${db.jdbc.driver}")
    private String jdbcDriver;
    @Value("${db.jdbc.url}")
    private String jdbcUrl;
    @Value("${db.jdbc.username}")
    private String jdbcUsername;
    @Value("${db.jdbc.password}")
    private String jdbcPassword;
    
    // mysql config class
    // ..... 
    
}

    RandomValuePropertySource 可以用來生成測試所需要的各種不同類型的隨機值,從而免去了在代碼中生成的麻煩。RandomValuePropertySource 可以生成數字和字符串。數字的類型包含 int 和 long,可以限定數字的大小範圍。以“random.”作爲前綴的配置屬性名稱由 RandomValuePropertySource 來生成.

屬性文件

    屬性文件是最常見的管理配置屬性的方式。Spring Boot 提供的 SpringApplication 類會搜索並加載 application.properties 文件來獲取配置屬性值。SpringApplication 類會在下面位置搜索該文件。

    1. 當前目錄的“/config”子目錄。
    2. 當前目錄。
    3. classpath 中的“/config”包。
    4. classpath

這個順序也表示了該位置上包含的屬性文件的優先級。優先級按照從高到低的順序排列。可以通過“spring.config.name”配置屬性來指定不同的屬性文件名稱。也可以通過“spring.config.location”來添加額外的屬性文件的搜索路徑。如果應用中包含多個 profile,可以爲每個 profile 定義各自的屬性文件,按照“application-{profile}”來命名。對於配置屬性,可以在代碼中通過“@Value”來使用。

@Value("${name}")中的值按照層級通過點來區分,比如要取到active的值。就需要寫成@Value("${spring.profiles.active}").

YAML
相對於屬性文件來說,YAML 是一個更好的配置文件格式。YAML 在 Ruby on Rails 中得到了很好的應用。SpringApplication 類也提供了對 YAML 配置文件的支持,只需要添加對 SnakeYAML 的依賴即可。比如:

spring:
 profiles: development
db:
 url: jdbc:hsqldb:file:testdb
 username: sa
 password:
---
spring:
 profiles: test
db:
 url: jdbc:mysql://localhost/test
 username: test
 password: test

這個實例的 YAML 文件中同時給出了 development 和 test 兩個不同的 profile 的配置信息,這也是 YAML 文件相對於屬性文件的優勢之一。除了使用“@Value”註解綁定配置屬性值之外,還可以使用更加靈活的方式。

@Component
@ConfigurationProperties(prefix="db")
public class DBSettings {
 private String url;
 private String username;
 private String password;
}
給出的是使用代碼清單 5 中的 YAML 文件的 Java 類。通過“@ConfigurationProperties(prefix="db")”註解,配置屬性中以“db”爲前綴的屬性值會被自動綁定到 Java 類中同名的域上,如 url 域的值會對應屬性“db.url”的值。只需要在應用的配置類中添加“@EnableConfigurationProperties”註解就可以啓用該自動綁定功能。

 

我這裏還有一個疑問,這個是怎麼注入進來的呢?
我們在項目啓動的時候,總是需要先啓動一些初始化的類,比較常見的做法是寫再static塊中,Spring Boot提供了一個CommandLineRunner接口,實現這個接口的類總是會被優先啓動,並優先執行CommandLineRunner接口中提供的run()方法。比如:

public class ApplicationConfigure implements CommandLineRunner  {

    @Value("${db.jdbc.driver}")
    private String jdbcDriver;
    @Value("${db.jdbc.url}")
    private String jdbcUrl;
    @Value("${db.jdbc.username}")
    private String jdbcUsername;
    @Value("${db.jdbc.password}")
    private String jdbcPassword;
    
    // mysql config class
    // ..... 
    @Override
    public void run(String... strings) throws Exception {
        // 預先加載的一些方法,類,屬性。
    }
}
如果有多個CommandLineRunner接口實現類,那麼可以通過註解@Order來規定所有實現類的運行順序。

這裏有的是我借鑑網上的一些描述,現在還不能完全深刻明白這些內容。有些內容是我真實運行項目截圖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章