一般在一個項目中,總是會有好多個環境。比如:
開發環境 -> 測試環境 -> 預發布環境 -> 生產環境
每個環境上的配置文件總是不一樣的,甚至開發環境中每個開發者的環境可能也會有一點不同,配置讀取可是一個讓人有點傷腦筋的問題。
Spring Boot提供了一種優先級配置讀取的機制來幫助我們從這種困境中走出來。
常規情況下,我們都知道Spring Boot的配置會從application.properties
中讀取。實際上,從resource
目錄下的application.properties
文件讀取是Spring Boot配置鏈中的一環而已。
根據Spring Boot的文檔,配置使用的優先級從高到低的順序,具體如下所示:
1. 命令行參數。
2. 通過 System.getProperties() 獲取的 Java 系統參數。
3. 操作系統環境變量。
4. 從 java:comp/env 得到的 JNDI 屬性。
5. 通過 RandomValuePropertySource 生成的“random.*”屬性。
6. 應用 Jar 文件之外的屬性文件(application.properties)。
7. 應用 Jar 文件內部的屬性文件(application.properties)。
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
這樣一來,我們在開發者的機器上總是使用自己的配置,而一到對應的環境,就會使用高級的位置所做的配置。
在代碼中讀取這些配置也是非常方便的,在代碼的邏輯中,其實是無需去關心這個配置是從什么地方來的,只用關注能獲取什么配置就夠了。
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
// .....
}
有時候我們在項目啟動的時候,總是需要先啟動一些初始化的類,以前比較常見的做法是寫再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
來規定所有實現類的運行順序。
通過這一系列API的幫助,Spring Boot讓環境配置變得輕松很多。