Spring 的 Environment 結合了兩個關注點:解析設定屬性,以及判定哪些 Bean 定義設定檔處於啟用狀態。核心框架定義了抽象化以及標準 JVM/Servlet 來源;Spring Boot 則增加了自己的外部設定來源與優先順序規則。
屬性來源與優先順序 #
可設定的環境在 MutablePropertySources 中維護依序排列的 PropertySource<?> 物件。解析會從優先順序最高的來源開始,依序向優先順序較低的來源搜尋,並回傳第一個包含所要求索引鍵的來源中的值。明確命名並排序屬性來源,可以避免設定隨註冊順序改變:
ConfigurableEnvironment environment = context.getEnvironment();
environment.getPropertySources().addFirst(
new MapPropertySource("deployment", Map.of("orders.timeout", "2s")));StandardEnvironment 包含 JVM 系統屬性與作業系統環境變數。StandardServletEnvironment 增加 Servlet 設定、Servlet context 參數,以及選擇性加入 JNDI 來源。處理設定類別時,@PropertySource 可以加入屬性資源。
來源順序是一項策略,而不是一條要求每個檔案、JVM 屬性或環境變數都必須勝出的內在規則。Spring Boot 定義了更大且有文件說明的順序,其中包括設定資料與命令列引數。測試應加入明確的測試來源,而不應依賴開發者電腦的環境。
解析、預設值與型別 #
PropertyResolver API 支援直接查詢與型別化查詢:
Duration timeout =
environment.getProperty("orders.timeout", Duration.class, Duration.ofSeconds(1));型別化存取會委派給已設定的轉換服務。預留位置語法支援 ${orders.timeout},以及 ${orders.timeout:1s} 這類回退值。當 context 具有適當的嵌入值解析器時,@Value 會使用預留位置解析;在明確的非 Boot 設定中,PropertySourcesPlaceholderConfigurer 提供這項功能。
只有在預設值於作業層面有效時,回退值才適用。可以在 Bean 使用必要設定之前宣告並驗證這些設定:
environment.setRequiredProperties("database.url", "database.user");
environment.validateRequiredProperties();未解析的必要預留位置應使啟動失敗,而不是靜默選取不適合生產環境的值。秘密資訊應透過受控的屬性來源輸入,並且在診斷解析問題時不得列印。
設定檔運算式 #
@Profile 會使元件或設定類別依據啟用的設定檔進行條件化。設定檔運算式支援名稱、使用 ! 的否定、使用 & 的合取、使用 | 的析取,以及括號:
@Configuration
@Profile("production & !maintenance")
class ProductionConfiguration {
}對於 @Profile({"blue", "green"}) 這類陣列,只要任一元素符合,元件就會被啟用。未指定設定檔的定義,不論啟用集合為何都仍符合條件。
當沒有明確啟用任何設定檔時,Spring 會使用預設設定檔集合,其初始值包含 default。spring.profiles.default 可以變更該集合。因此,標記為 @Profile("default") 的 Bean 是有條件的;當其他設定檔處於啟用狀態時,它並不是無條件的回退實作。
啟用設定檔 #
可以在重新整理之前以程式方式選取設定檔:
var context = new AnnotationConfigApplicationContext();
context.getEnvironment().setActiveProfiles("integration");
context.register(TestConfiguration.class);
context.refresh();設定檔也可以來自 spring.profiles.active 屬性。JVM 的 -Dspring.profiles.active=production 可與核心標準環境搭配使用。依據 Boot 的外部設定規則,Spring Boot 另外接受命令列設定,以及像 SPRING_PROFILES_ACTIVE 這類寬鬆的環境變數名稱。依使用 setActiveProfiles 或 addActiveProfile 而定,程式呼叫會取代環境的啟用集合,或將設定檔加入其中。
確定性設定 #
在生產環境與測試中套用相同的明確策略:
- 記錄來源名稱與優先順序。
- 在重新整理 context 前啟用設定檔。
- 對測試擁有的值使用
@TestPropertySource或@DynamicPropertySource。 - 在專門的設定測試中,斷言關鍵的已解析值。
- 保持設定檔的粒度較粗;對於值使用屬性,而不是為每種設定組合建立一個設定檔。
評論
在 GitHub 上閱讀或評論(發表評論需要登入)