Spring boot 配置類與配置文件詳解

Spring boot 配置類與配置文件詳解

前言

在現今Spring boot 流行年代,相信大部人都非常喜歡Spring boot簡潔而非常有效的配置,讓我們從龐大xml配置解放出來,讓每個框架都需要手動配置集成的勞動中解放出來。這一切都是spring Boot基於約定優於配置的思想,大量的減少了配置文件的使用。

@SpringBootApplication註解

一個簡單的@SpringBootApplication註解可以試下這那三個功能:

  • @EnableAutoConfiguration: 啟動Spring boot 的自動化配置機制
  • @ComponentScan : 在程序所在的包下面啟用組件掃描
  • @Configuration: 允許在上下文中註冊額外的bean或導入其他配置類

Spring boot的配置類

Spring boot 偏好於基於Java類的配置,儘管SpringApplication也可以和XML配置一起使用,但是Spring boot建議我們的配置寫在單個 @Configuration 註解的類中,通常,Spring boot 官方聲稱定義主方法的類作為主@configuration是一個很好的選擇。但我們也可以根據我們的業務需要寫多個@configuration,比如說 數據庫連接配置一個 @configuration,線程池配置一個 @configuration等等

導入配置類

我們不需要將所有@configuration放到一個類中。@import註解可用於導入其他配置類。或者,您可以使用@components can自動掃描所有Spring組件,包括@configuration類。

@SpringBootApplication
@Import({LinkConfig.class, ConnectionPoolConfig.class, HttpConfig.class, CuratorConfig.class, GlobalConfig.class})
public class ExampleController

導入xml配置

如果你一定要使用基於xml的配置,建議仍然從@configuration類開始。然後可以使用@ImportResource註解加載XML配置文件

SpringBootApplication
@ImportResource("classpath:*.xml")
public class ExampleController

自動配置

Spring Boot自動配置功能會嘗試根據你添加的JAR依賴項自動配置您的Spring應用程序。例如,如果hsqldb在你的類路徑上,並且你沒有手動配置任何數據庫連接bean,那麼spring boot會自動為你配置一個內存數據庫。

你只需要選擇自動配置,方法是將@EnableAutoconfiguration或@SpringBootApplication註釋添加到您的@configuration類中。

注意:你應該只添加一個@SpringBootApplication或@EnableAutoconfiguration註解。我們通常建議您只向主要@configuration類添加一個註解(主要configuration 是帶main方法的啟動類)

自動化配置是非侵入式的,在任何一個點上,你可以定義你自己的配置去替換 auto-configuration 引入的配置。例如,你添加了自己的數據源配置,則auto-configuration 帶進來的數據配置將會無效。

禁用部分自動配置類

如果你發現一些不想應用的特定自動配置類,可以使用@EnableAutoconfiguration的exclude屬性禁用它們,如下例所示:

@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class ExampleController

Spring boot 的配置文件

Spring boot允許將配置外部化,以便應用程序代碼在不同的環境中使用不同的配置。可以使用properties文件、yaml文件、環境變量和命令行參數來外部化配置。屬性值可以通過使用@value註解直接注入bean,通過Spring的環境抽象訪問,或者通過@ConfigurationProperties綁定到結構化對象。

Spring Boot使用一個非常特殊的屬性源順序,這樣設計是為了個這些配置一個優先級,以便於進行的合理覆蓋。屬性按以下順序:

  1. 主目錄上的devtools全局設置屬性(~/.spring-boot-devtools.properties,當devtools處於活動狀態時)
  2. @TestPropertySource 註解在你的測試代碼上
  3. @SpringBootTest 註解上的屬性值在測試代碼上,測試應用程序特殊部分的測試註解
  4. 命令行參數
  5. 來自於SPRING_APPLICATION_JSON 的參數屬性值,(嵌入在環境變量或系統屬性中的內聯JSON)
  6. ServletConfig 初始化的參數
  7. ServletContext 初始化參數
  8. 來自 java:comp/env 的JNDI 屬性值
  9. Java System 的屬性(System.getProperties())
  10. 系統環境變量
  11. 僅在RandomValuePropertySource*中具有屬性的RandomValuePropertySource。
  12. 在打包的JAR之外配置特定的Profile-specific.properties(application-{profile}.properties 和yaml 文件)
  13. 在打包的JAR裡面配置特定的Profile-specific.properties(application-{profile}.properties 或yaml 文件)
  14. 在打包的JAR之外的 application.properties或yaml 文件
  15. 在打包的JAR裡面的 application properties(application.properties 或yaml 文件)
  16. @PropertySource註解在你的 @Configuration 配置類上
  17. 默認屬性(通過設置SpringApplication.setDefaultProperties指定)

下面舉個例子,假如你開發了一個使用name屬性的@component,如下例所示:

@Component
public class ComBean {
@Value("${name}")
private String name;
}

在應用程序classpath路徑(例如,在JAR中)上,可以有一個application.properties文件,該文件為name提供了一個合理的默認屬性值。在新環境中運行時,可以在jar外部提供application.properties文件來覆蓋name 屬性。對於一次性測試,您可以使用特定的命令行開關(例如java –jar app.jar --name=”String”)啟動。

在前面的示例中,您將在Spring環境中得到name=test。您還可以在系統屬性中以spring.application.json的形式提供json,如下例所示:

java -Dspring.application.json='{"name":"test"}' -jar myapp.jar

還可以使用命令行參數提供JSON,如下例所示:

java -jar myapp.jar --spring.application.json='{"name":"test"}'

RandomValuePropertySource配置隨機數

RandomValuePropertySource對於生產注入隨機值(例如,到機密或測試用例中)很有用。它可以生成整數、long、uuid或字符串,如下例所示:

my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}

訪問命令行參數

默認情況下,SpringApplication會將任何命令行選項參數(即以-開頭的參數,例如--server.port=9000)轉換為屬性,並將其添加到Spring環境中。如前所述,命令行屬性總是優先於其他屬性源。

如果不希望將命令行屬性添加到環境中,可以使用

SpringApplication.setAddCommandLineProperties(false)

Application 屬性文件

SpringApplication從以下位置的application.properties文件加載屬性,並將其添加到Spring環境中:

  1. 當前目錄的 /config 子目錄
  2. 當前目錄
  3. classpath 的 /config 包
  4. classpath 的根目錄

3 和 4 是實際項目應用比較常見

列表按優先級排序(在列表中較高位置定義的屬性覆蓋在較低位置定義的屬性)。

如果不喜歡application.properties作為配置文件名,可以通過指定spring.config.name環境屬性切換到另一個文件名。還可以使用spring.config.location環境屬性(目錄位置或文件路徑的逗號分隔列表)引用顯式位置。以下示例顯示如何指定其他文件名:

java -jar myproject.jar --spring.config.name=myproject

以下示例顯示如何指定兩個位置:

java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties

如果spring.config.location包含目錄(與文件相反),那麼它們應該以/結尾,並且在運行時,在加載之前,附加從spring.config.name生成的名稱,包括特定文件的文件名)。spring.config.location中指定的文件按原樣使用,不支持特定於概要文件的變量,並且被任何特定於概要文件的屬性覆蓋。

按相反的順序搜索配置位置。默認情況下,配置的位置為classpath/、classpath:/config/、file:../、file:../config/。結果搜索順序如下:

  1. file:./config/
  2. file:./
  3. classpath:/config/
  4. classpath:/

當使用spring.config.location配置自定義配置位置時,它們將替換默認位置。例如,如果spring.config.location配置了值classpath:/custom config/,file:/custom config/,則搜索順序如下:

  1. file:./custom-config/
  2. classpath:custom-config/

或者,當使用spring.config.additional-location配置自定義配置位置時,除了默認位置外,還將使用這些位置。在默認位置之前搜索其他位置。例如,如果配置了classpath:/custom config/,file:/custom config/的其他位置,則搜索順序如下:

  1. file:./custom-config/
  2. classpath:custom-config/
  3. file:./config/
  4. file:./
  5. classpath:/config/
  6. classpath:/

此搜索順序允許您在一個配置文件中指定默認值,然後有選擇地在另一個配置文件中覆蓋這些值。您可以在默認位置的application.properties(或用spring.config.name選擇的任何其他基名稱)中為應用程序提供默認值。然後,可以在運行時使用位於其中一個自定義位置的其他文件覆蓋這些默認值。

Profile-specific Properties

除了application.properties文件外,還可以使用以下命名約定定義特定於文件的屬性:application-{profile}.properties。環境有一組默認配置文件(默認情況下為[default]),如果未設置活動配置文件,則使用這些默認配置文件。換句話說,如果沒有顯式激活配置文件,那麼將加載application-default.properties中的屬性。

配置文件特定的屬性從與標準application.properties相同的位置加載,配置文件總是覆蓋非特定的文件,無論配置文件是在打包的jar內還是在打包的jar外。

如果指定了多個配置文件,則應用最後一個勝利策略。例如,spring.profiles.active屬性指定的配置文件將添加到通過SpringApplication API配置的配置文件之後,因此優先。

如果在spring.config.location中指定了任何文件,則不會考慮這些文件的特定於概要文件的變體。如果還想使用特定於概要文件的屬性,請使用spring.config.location中的目錄。

屬性中的佔位符

application.properties中的值在使用時通過現有環境進行過濾,因此您可以引用以前定義的值(例如,從系統屬性)

app.name=MyApp
app.description=${app.name} is a Spring Boot application

Profiles

Spring配置文件提供了一種隔離應用程序配置部分的方法,使其僅在特定環境中可用。任何@component或@configuration在加載時都可以用@profile進行標記以限制,如下例所示:

@Configuration
@Profile("production")
public class ProductionConfiguration {
// ...
}

可以使用spring.profiles.active 環境屬性指定哪些配置文件處於活動狀態。例如,您可以將其包含在application.properties中,如下例所示:

spring.profiles.active=dev,hsqldb

您還可以使用以下開關在命令行上指定它:--spring.profiles.active=dev,hsqldb。

添加活動profile

spring.profiles.active屬性遵循與其他屬性相同的順序規則:最高的屬性源獲勝。這意味著您可以在application.properties中指定活動配置文件,然後可以使用命令行開關替換它們。

有時,將特定於概要文件的屬性添加到活動概要文件中而不是替換它們是很有用的。spring.profiles.include屬性可用於無條件添加活動配置文件。SpringApplication入口點也有一個Java API來設置附加的配置文件(也就是說,在spring.profiles.active屬性激活的那些文件之上)。請參見SpringApplication中的setAdditionalProfiles()方法

例如,當使用開關-spring.profiles.active=prod運行具有以下屬性的應用程序時,還會激活proddb和prodmq配置文件:

---
my.property: fromyamlfile
---
spring.profiles: prod
spring.profiles.include:
- proddb
- prodmq


分享到:


相關文章: