前言
在現(xiàn)今Spring boot 流行年代,相信大部人都非常喜歡Spring boot簡(jiǎn)潔而非常有效的配置,讓我們從龐大xml配置解放出來,讓每個(gè)框架都需要手動(dòng)配置集成的勞動(dòng)中解放出來。這一切都是spring Boot基于約定優(yōu)于配置的思想,大量的減少了配置文件的使用。
@SpringBootApplication注解
一個(gè)簡(jiǎn)單的@SpringBootApplication注解可以試下這那三個(gè)功能:
- @EnableAutoConfiguration: 啟動(dòng)Spring boot 的自動(dòng)化配置機(jī)制
- @ComponentScan : 在程序所在的包下面啟用組件掃描
- @Configuration: 允許在上下文中注冊(cè)額外的bean或?qū)肫渌渲妙?/li>
Spring boot的配置類
Spring boot 偏好于基于JAVA類的配置,盡管SpringApplication也可以和XML配置一起使用,但是Spring boot建議我們的配置寫在單個(gè) @Configuration 注解的類中,通常,Spring boot 官方聲稱定義主方法的類作為主@configuration是一個(gè)很好的選擇。但我們也可以根據(jù)我們的業(yè)務(wù)需要寫多個(gè)@configuration,比如說 數(shù)據(jù)庫(kù)連接配置一個(gè) @configuration,線程池配置一個(gè) @configuration等等
導(dǎo)入配置類
我們不需要將所有@configuration放到一個(gè)類中。@import注解可用于導(dǎo)入其他配置類?;蛘?,您可以使用@components can自動(dòng)掃描所有Spring組件,包括@configuration類。
@SpringBootApplication @Import({LinkConfig.class, ConnectionPoolConfig.class, HttpConfig.class, CuratorConfig.class, GlobalConfig.class}) public class ExampleController
導(dǎo)入xml配置
如果你一定要使用基于xml的配置,建議仍然從@configuration類開始。然后可以使用@ImportResource注解加載XML配置文件
SpringBootApplication @ImportResource("classpath:*.xml") public class ExampleController
自動(dòng)配置
Spring Boot自動(dòng)配置功能會(huì)嘗試根據(jù)你添加的JAR依賴項(xiàng)自動(dòng)配置您的Spring應(yīng)用程序。例如,如果hsqldb在你的類路徑上,并且你沒有手動(dòng)配置任何數(shù)據(jù)庫(kù)連接bean,那么spring boot會(huì)自動(dòng)為你配置一個(gè)內(nèi)存數(shù)據(jù)庫(kù)。
你只需要選擇自動(dòng)配置,方法是將@EnableAutoconfiguration或@SpringBootApplication注釋添加到您的@configuration類中。
注意:你應(yīng)該只添加一個(gè)@SpringBootApplication或@EnableAutoconfiguration注解。我們通常建議您只向主要@configuration類添加一個(gè)注解(主要configuration 是帶main方法的啟動(dòng)類)
自動(dòng)化配置是非侵入式的,在任何一個(gè)點(diǎn)上,你可以定義你自己的配置去替換 auto-configuration 引入的配置。例如,你添加了自己的數(shù)據(jù)源配置,則auto-configuration 帶進(jìn)來的數(shù)據(jù)配置將會(huì)無(wú)效。
禁用部分自動(dòng)配置類
如果你發(fā)現(xiàn)一些不想應(yīng)用的特定自動(dòng)配置類,可以使用@EnableAutoconfiguration的exclude屬性禁用它們,如下例所示:
@Configuration @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) public class ExampleController
Spring boot 的配置文件
Spring boot允許將配置外部化,以便應(yīng)用程序代碼在不同的環(huán)境中使用不同的配置??梢允褂胮roperties文件、yaml文件、環(huán)境變量和命令行參數(shù)來外部化配置。屬性值可以通過使用@value注解直接注入bean,通過Spring的環(huán)境抽象訪問,或者通過@ConfigurationProperties綁定到結(jié)構(gòu)化對(duì)象。
Spring Boot使用一個(gè)非常特殊的屬性源順序,這樣設(shè)計(jì)是為了個(gè)這些配置一個(gè)優(yōu)先級(jí),以便于進(jìn)行的合理覆蓋。屬性按以下順序:
- 主目錄上的devtools全局設(shè)置屬性(~/.spring-boot-devtools.properties,當(dāng)devtools處于活動(dòng)狀態(tài)時(shí))
- @TestPropertySource 注解在你的測(cè)試代碼上
- @SpringBootTest 注解上的屬性值在測(cè)試代碼上,測(cè)試應(yīng)用程序特殊部分的測(cè)試注解
- 命令行參數(shù)
- 來自于SPRING_APPLICATION_JSON 的參數(shù)屬性值,(嵌入在環(huán)境變量或系統(tǒng)屬性中的內(nèi)聯(lián)JSON)
- ServletConfig 初始化的參數(shù)
- ServletContext 初始化參數(shù)
- 來自 java:comp/env 的JNDI 屬性值
- Java System 的屬性(System.getProperties())
- 系統(tǒng)環(huán)境變量
- 僅在RandomValuePropertySource*中具有屬性的RandomValuePropertySource。
- 在打包的JAR之外配置特定的Profile-specific.properties(application-{profile}.properties 和yaml 文件)
- 在打包的JAR里面配置特定的Profile-specific.properties(application-{profile}.properties 或yaml 文件)
- 在打包的JAR之外的 application.properties或yaml 文件
- 在打包的JAR里面的 application properties(application.properties 或yaml 文件)
- @PropertySource注解在你的 @Configuration 配置類上
- 默認(rèn)屬性(通過設(shè)置SpringApplication.setDefaultProperties指定)
下面舉個(gè)例子,假如你開發(fā)了一個(gè)使用name屬性的@component,如下例所示:
@Component public class ComBean { @Value("${name}") private String name; }
在應(yīng)用程序classpath路徑(例如,在JAR中)上,可以有一個(gè)application.properties文件,該文件為name提供了一個(gè)合理的默認(rèn)屬性值。在新環(huán)境中運(yùn)行時(shí),可以在jar外部提供application.properties文件來覆蓋name 屬性。對(duì)于一次性測(cè)試,您可以使用特定的命令行開關(guān)(例如java –jar app.jar --name=”String”)啟動(dòng)。
在前面的示例中,您將在Spring環(huán)境中得到name=test。您還可以在系統(tǒng)屬性中以spring.application.json的形式提供json,如下例所示:
java -Dspring.application.json='{"name":"test"}' -jar myapp.jar
還可以使用命令行參數(shù)提供JSON,如下例所示:
java -jar myapp.jar --spring.application.json='{"name":"test"}'
RandomValuePropertySource配置隨機(jī)數(shù)
RandomValuePropertySource對(duì)于生產(chǎn)注入隨機(jī)值(例如,到機(jī)密或測(cè)試用例中)很有用。它可以生成整數(shù)、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]}
訪問命令行參數(shù)
默認(rèn)情況下,SpringApplication會(huì)將任何命令行選項(xiàng)參數(shù)(即以-開頭的參數(shù),例如--server.port=9000)轉(zhuǎn)換為屬性,并將其添加到Spring環(huán)境中。如前所述,命令行屬性總是優(yōu)先于其他屬性源。
如果不希望將命令行屬性添加到環(huán)境中,可以使用
SpringApplication.setAddCommandLineProperties(false)
Application 屬性文件
SpringApplication從以下位置的application.properties文件加載屬性,并將其添加到Spring環(huán)境中:
- 當(dāng)前目錄的 /config 子目錄
- 當(dāng)前目錄
- classpath 的 /config 包
- classpath 的根目錄
3 和 4 是實(shí)際項(xiàng)目應(yīng)用比較常見
列表按優(yōu)先級(jí)排序(在列表中較高位置定義的屬性覆蓋在較低位置定義的屬性)。
如果不喜歡application.properties作為配置文件名,可以通過指定spring.config.name環(huán)境屬性切換到另一個(gè)文件名。還可以使用spring.config.location環(huán)境屬性(目錄位置或文件路徑的逗號(hào)分隔列表)引用顯式位置。以下示例顯示如何指定其他文件名:
java -jar myproject.jar --spring.config.name=myproject
以下示例顯示如何指定兩個(gè)位置:
java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
如果spring.config.location包含目錄(與文件相反),那么它們應(yīng)該以/結(jié)尾,并且在運(yùn)行時(shí),在加載之前,附加從spring.config.name生成的名稱,包括特定文件的文件名)。spring.config.location中指定的文件按原樣使用,不支持特定于概要文件的變量,并且被任何特定于概要文件的屬性覆蓋。
按相反的順序搜索配置位置。默認(rèn)情況下,配置的位置為classpath/、classpath:/config/、file:../、file:../config/。結(jié)果搜索順序如下:
- file:./config/
- file:./
- classpath:/config/
- classpath:/
當(dāng)使用spring.config.location配置自定義配置位置時(shí),它們將替換默認(rèn)位置。例如,如果spring.config.location配置了值classpath:/custom config/,file:/custom config/,則搜索順序如下:
- file:./custom-config/
- classpath:custom-config/
或者,當(dāng)使用spring.config.additional-location配置自定義配置位置時(shí),除了默認(rèn)位置外,還將使用這些位置。在默認(rèn)位置之前搜索其他位置。例如,如果配置了classpath:/custom config/,file:/custom config/的其他位置,則搜索順序如下:
- file:./custom-config/
- classpath:custom-config/
- file:./config/
- file:./
- classpath:/config/
- classpath:/
此搜索順序允許您在一個(gè)配置文件中指定默認(rèn)值,然后有選擇地在另一個(gè)配置文件中覆蓋這些值。您可以在默認(rèn)位置的application.properties(或用spring.config.name選擇的任何其他基名稱)中為應(yīng)用程序提供默認(rèn)值。然后,可以在運(yùn)行時(shí)使用位于其中一個(gè)自定義位置的其他文件覆蓋這些默認(rèn)值。
Profile-specific Properties
除了application.properties文件外,還可以使用以下命名約定定義特定于文件的屬性:application-{profile}.properties。環(huán)境有一組默認(rèn)配置文件(默認(rèn)情況下為[default]),如果未設(shè)置活動(dòng)配置文件,則使用這些默認(rèn)配置文件。換句話說,如果沒有顯式激活配置文件,那么將加載application-default.properties中的屬性。
配置文件特定的屬性從與標(biāo)準(zhǔn)application.properties相同的位置加載,配置文件總是覆蓋非特定的文件,無(wú)論配置文件是在打包的jar內(nèi)還是在打包的jar外。
如果指定了多個(gè)配置文件,則應(yīng)用最后一個(gè)勝利策略。例如,spring.profiles.active屬性指定的配置文件將添加到通過SpringApplication API配置的配置文件之后,因此優(yōu)先。
如果在spring.config.location中指定了任何文件,則不會(huì)考慮這些文件的特定于概要文件的變體。如果還想使用特定于概要文件的屬性,請(qǐng)使用spring.config.location中的目錄。
屬性中的占位符
application.properties中的值在使用時(shí)通過現(xiàn)有環(huán)境進(jìn)行過濾,因此您可以引用以前定義的值(例如,從系統(tǒng)屬性)
app.name=MyApp app.description=${app.name} is a Spring Boot application
Profiles
Spring配置文件提供了一種隔離應(yīng)用程序配置部分的方法,使其僅在特定環(huán)境中可用。任何@component或@configuration在加載時(shí)都可以用@profile進(jìn)行標(biāo)記以限制,如下例所示:
@Configuration @Profile("production") public class ProductionConfiguration { // ... }
可以使用spring.profiles.active 環(huán)境屬性指定哪些配置文件處于活動(dòng)狀態(tài)。例如,您可以將其包含在application.properties中,如下例所示:
spring.profiles.active=dev,hsqldb
您還可以使用以下開關(guān)在命令行上指定它:--spring.profiles.active=dev,hsqldb。
添加活動(dòng)profile
spring.profiles.active屬性遵循與其他屬性相同的順序規(guī)則:最高的屬性源獲勝。這意味著您可以在application.properties中指定活動(dòng)配置文件,然后可以使用命令行開關(guān)替換它們。
有時(shí),將特定于概要文件的屬性添加到活動(dòng)概要文件中而不是替換它們是很有用的。spring.profiles.include屬性可用于無(wú)條件添加活動(dòng)配置文件。SpringApplication入口點(diǎn)也有一個(gè)Java API來設(shè)置附加的配置文件(也就是說,在spring.profiles.active屬性激活的那些文件之上)。請(qǐng)參見SpringApplication中的setAdditionalProfiles()方法
例如,當(dāng)使用開關(guān)-spring.profiles.active=prod運(yùn)行具有以下屬性的應(yīng)用程序時(shí),還會(huì)激活proddb和prodmq配置文件:
--- my.property: fromyamlfile --- spring.profiles: prod spring.profiles.include: - proddb - prodmq