SpringBoot配置文件啟動(dòng)加載順序的方法步驟
前言
Spring Boot的啟動(dòng)加載順序是一個(gè)涉及多個(gè)步驟和組件的過(guò)程。Spring Boot通過(guò)一系列默認(rèn)設(shè)置簡(jiǎn)化了應(yīng)用程序的配置,使得開(kāi)發(fā)者能夠快速地搭建和部署應(yīng)用。為了實(shí)現(xiàn)這一目標(biāo),Spring Boot采用了一種分層和優(yōu)先級(jí)機(jī)制來(lái)加載配置文件。
一、Spring Boot 配置文件的加載順序
1)bootstrap.properties 或 bootstrap.yml (如果存在)
application.properties 或 application.yml
2)命令行參數(shù)
3)操作系統(tǒng)環(huán)境變量
4)從 RandomValuePropertySource 生成的 random.* 屬性
5)由 @TestPropertySource 注解聲明的屬性
6)由 @SpringBootTest 注解并且 #properties 注解屬性的測(cè)試屬性
7)由 SpringBootApplication 注解的 exclude 屬性排除的自動(dòng)配置的類(lèi)
8)由應(yīng)用程序的 RandomValuePropertySource 生成的 random.* 屬性
9)在 application.properties 或 application.yml 中使用 SpringApplication 的 setDefaultProperties 方法設(shè)置的屬性
這個(gè)加載順序是有意為此的,因?yàn)橛行傩孕枰诤罄m(xù)加載的時(shí)候覆蓋前面的同名屬性。
這里是一個(gè)簡(jiǎn)單的例子,演示如何使用 bootstrap.properties 來(lái)配置一些在 Spring Boot 啟動(dòng)時(shí)需要的屬性:
bootstrap.properties
# bootstrap.properties spring.application.name=myapp spring.profiles.active=prod
或者 application.yml:
# application.yml server: port: 8080
命令行參數(shù)可以用于覆蓋特定的屬性,例如:
java -jar myapp.jar --server.port=9090
二、在Spring Boot中,配置文件的加載順序遵循以下步驟
- 自動(dòng)加載:Spring Boot在啟動(dòng)時(shí)會(huì)掃描特定位置的配置文件。這些位置包括jar包內(nèi)的classpath路徑、當(dāng)前項(xiàng)目的根目錄以及桌面上的文件路徑。Spring Boot會(huì)優(yōu)先加載高優(yōu)先級(jí)的配置文件,并在低優(yōu)先級(jí)配置文件被加載時(shí)覆蓋掉沖突的屬性。
- 自定義配置文件:開(kāi)發(fā)者可以通過(guò)spring.config.name屬性指定自定義配置文件名。Spring Boot會(huì)按照以下順序查找這些配置文件:application.和application-default.,并根據(jù)擴(kuò)展名的優(yōu)先級(jí)進(jìn)行加載。擴(kuò)展名包括:.properties、.xml、.yml、.yaml。
- 命令行參數(shù):開(kāi)發(fā)者可以在命令行中指定一些參數(shù)來(lái)覆蓋默認(rèn)的配置值。這些參數(shù)將優(yōu)先于任何其他配置文件中的值生效。
- 環(huán)境變量:環(huán)境變量也可以用來(lái)覆蓋配置文件中的屬性值。這些變量在應(yīng)用程序啟動(dòng)時(shí)自動(dòng)加載,無(wú)需額外操作。
- 屬性占位符:在配置文件中,可以使用${...}語(yǔ)法來(lái)引用其他屬性的值。這種方式可以創(chuàng)建依賴(lài)關(guān)系,使得某些屬性在其他屬性被解析后才能確定其值。
- 自動(dòng)配置類(lèi):Spring Boot提供了一系列的自動(dòng)配置類(lèi),可以根據(jù)項(xiàng)目需求自動(dòng)配置一些組件。開(kāi)發(fā)者可以通過(guò)禁用特定的自動(dòng)配置類(lèi)或自定義自動(dòng)配置類(lèi)來(lái)覆蓋默認(rèn)設(shè)置。
- 條件注解:Spring Boot允許使用條件注解來(lái)控制特定組件的創(chuàng)建。例如,只有當(dāng)某個(gè)屬性存在或滿(mǎn)足特定條件時(shí),某個(gè)bean才會(huì)被創(chuàng)建。
- 外部化配置:Spring Boot支持將部分配置移動(dòng)到外部屬性文件中,以提高可維護(hù)性和復(fù)用性。這些外部屬性文件可以包含在jar包內(nèi)部、當(dāng)前項(xiàng)目根目錄或其他指定位置。
總結(jié)來(lái)說(shuō),Spring Boot的配置加載順序遵循以下原則:優(yōu)先從高優(yōu)先級(jí)的源加載配置,并在低優(yōu)先級(jí)源加載時(shí)覆蓋沖突的屬性;開(kāi)發(fā)者可以通過(guò)自定義配置文件、命令行參數(shù)和環(huán)境變量來(lái)覆蓋默認(rèn)值;自動(dòng)配置類(lèi)和條件注解允許更靈活地控制組件的創(chuàng)建;而外部化配置則提高了應(yīng)用程序的維護(hù)性和復(fù)用性。了解這個(gè)加載順序有助于更好地管理和優(yōu)化Spring Boot應(yīng)用程序的配置。
關(guān)鍵步驟劃分的Spring Boot啟動(dòng)加載順序的概述:
三、啟動(dòng)準(zhǔn)備階段
- 裝載核心啟動(dòng)器類(lèi):
org.springframework.boot.SpringApplication。 - 通過(guò)構(gòu)造函數(shù)創(chuàng)建
SpringApplication實(shí)例時(shí),進(jìn)行一系列的初始化工作。
四、配置加載階段
- Spring Boot項(xiàng)目會(huì)按照特定的順序加載配置文件,這些配置文件可以是application.properties或application.yml格式。
配置文件的加載順序(優(yōu)先級(jí)由高到低):
- file:./config/(項(xiàng)目根路徑下的config文件夾)
- file:./(項(xiàng)目根路徑)
- classpath:/config/(類(lèi)路徑下的config文件夾)
- classpath:/(類(lèi)路徑)

外部配置文件的加載方式:
- 命令行參數(shù):可以直接在啟動(dòng)命令后添加啟動(dòng)參數(shù)。
- spring.config.location:用于指定配置文件的新位置。
如果多個(gè)文件有相同的key,高優(yōu)先級(jí)的值會(huì)覆蓋低優(yōu)先級(jí)的值。
五、上下文準(zhǔn)備階段
- 準(zhǔn)備并刷新應(yīng)用上下文(Context)。
- 加載所有的初始化器(如從
META-INF/spring.factories配置文件中加載的)。 - 加載所有的監(jiān)聽(tīng)器(也是從
META-INF/spring.factories配置文件中加載的)。
六、啟動(dòng)執(zhí)行階段
- 觸發(fā)所有
CommandLineRunner執(zhí)行。 - 執(zhí)行自定義的初始化邏輯(如果有的話(huà))。
七、完成階段
- 啟動(dòng)完成,等待退出。
注意
- 帶profile的配置文件(如
application-dev.yml)通常具有比不帶profile的配置文件(如application.yml)更高的優(yōu)先級(jí)。
代碼演示,項(xiàng)目啟動(dòng)成功后執(zhí)行一段初始化邏輯:
八、啟動(dòng)main方法中添加初始化邏輯
在Spring Boot的main入口啟動(dòng)方法中,執(zhí)行SpringApplication.run(LimitApplication.class, args)是可以返回ApplicationContext對(duì)象的,我們可以從ApplicationContext中獲取指定的bean對(duì)象,執(zhí)行初始化邏輯。
@SpringBootApplication(scanBasePackages = {"com.xinda.springbootday01.service"})
public class OrderApplication {
public static void main(String[] args){
//啟動(dòng)的run方法
ApplicationContext context = SpringApplication.run(OrderApplication.class, args);
//啟動(dòng)執(zhí)行操作:從context中獲取指定的bean,調(diào)度初始化邏輯
OrderService orderService = (OrderService)context.getBean("OrderServiceImpl");
orderService.preLoadCache();
}
}初始化邏輯:
@Service
public class OrderServiceImpl implements OrderService {
@Override
public void preLoadCache(){
System.out.println("應(yīng)用啟動(dòng)完成:開(kāi)始執(zhí)行緩存預(yù)加載操作");
}
}九、實(shí)現(xiàn)ApplicationRunner或CommandLineRunner接口
在Spring Boot框架中,給我們提供了ApplicationRunner和CommandLineRunner接口來(lái)幫助我們解決項(xiàng)目啟動(dòng)后的初始化資源操作。
如果有多個(gè)ApplicationRunner、CommandLineRunner的實(shí)現(xiàn)類(lèi),可以通過(guò)@Order注解進(jìn)行排序,參數(shù)值小的先執(zhí)行。
實(shí)現(xiàn)CommandLineRunner接口:
@Order(1)
@Component
@Slf4j
public class CommandLineRunnerImpl implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("應(yīng)用啟動(dòng)完成,開(kāi)始執(zhí)行CommandLineRunner方法完成資源初始化");
}
}實(shí)現(xiàn)ApplicationRunner接口:
@Order(2)
@Component
@Slf4j
public class ApplicationRunnerImpl implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("應(yīng)用啟動(dòng)完成,開(kāi)始執(zhí)行ApplicationRunner方法完成資源初始化");
}
}源碼分析:在SpringApplication的run方法中,有這么一段核心代碼
public ConfigurableApplicationContext run(String... args) {
long startTime = System.nanoTime();
DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
ConfigurableApplicationContext context = null;
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
this.configureIgnoreBeanInfo(environment);
Banner printedBanner = this.printBanner(environment);
context = this.createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), timeTakenToStartup);
}
listeners.started(context, timeTakenToStartup);
this.callRunners(context, applicationArguments);
} catch (Throwable var12) {
this.handleRunFailure(context, var12, listeners);
throw new IllegalStateException(var12);
}
try {
Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
listeners.ready(context, timeTakenToReady);
return context;
} catch (Throwable var11) {
this.handleRunFailure(context, var11, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var11);
}
}十、ApplicationListener監(jiān)聽(tīng)啟動(dòng)完成事件
通過(guò)源碼,我們發(fā)現(xiàn)在Spring Boot啟動(dòng)過(guò)程中,框架內(nèi)部定義了很多事件SpringApplicationEvent,用來(lái)通知SpringApplicationRunListeners監(jiān)聽(tīng)器,以針對(duì)各種事件執(zhí)行對(duì)應(yīng)的邏輯處理。而Spring Boot啟動(dòng)完成的事件對(duì)應(yīng)的是ApplicationStartedEvent,我們可以通過(guò)自定義監(jiān)聽(tīng)器來(lái)監(jiān)聽(tīng)ApplicationStartedEvent事件,然后執(zhí)行初始化資源的相關(guān)操作。
@Component
class StartedEventListener implements ApplicationListener<ApplicationStartedEvent> {
@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
System.out.println("應(yīng)用啟動(dòng)完成,通知監(jiān)聽(tīng)器執(zhí)行緩存預(yù)加載操作");
}
}總結(jié)
Spring Boot支持兩種類(lèi)型的配置文件:application.properties和application.yml。當(dāng)同一個(gè)目錄下同時(shí)存在這兩種類(lèi)型的配置文件時(shí),application.properties會(huì)優(yōu)先加載,但兩種文件會(huì)進(jìn)行互補(bǔ)配置。即,如果同一配置項(xiàng)在兩個(gè)配置文件中都進(jìn)行了設(shè)置,那么application.properties中的配置會(huì)覆蓋application.yml中的配置。
除了上述默認(rèn)的配置文件加載位置外,Spring Boot還支持多種外部配置方式,它們的優(yōu)先級(jí)從高到低如下:
1)命令行參數(shù):通過(guò)java -jar命令啟動(dòng)應(yīng)用時(shí),可以在命令后附加–配置項(xiàng)=值的形式來(lái)指定配置。
2)來(lái)自java:comp/env的JNDI屬性。
3)Java系統(tǒng)屬性(System.getProperties())。
4)操作系統(tǒng)環(huán)境變量。
5)RandomValuePropertySource配置的random.*屬性值:用于生成隨機(jī)值。
6)jar包外部的帶profile的配置文件(如application-{profile}.properties或application-{profile}.yml)。
7)jar包內(nèi)部的帶profile的配置文件。
8)jar包外部的不帶profile的配置文件(如application.properties或application.yml)。
9)jar包內(nèi)部的不帶profile的配置文件。
(由jar包外向jar包內(nèi)進(jìn)行尋找,優(yōu)先加載帶profile的,再加載不帶profile的。)
10)@Configuration注解類(lèi)上的@PropertySource。
11)通過(guò)SpringApplication.setDefaultProperties指定的默認(rèn)屬性。
另外,可以通過(guò)spring.config.location屬性來(lái)改變默認(rèn)的配置文件位置。
在項(xiàng)目打包后,可以使用命令行參數(shù)的形式來(lái)指定配置文件的新位置,指定的配置文件和默認(rèn)加載的配置文件會(huì)共同起作用,形成互補(bǔ)配置。
當(dāng)使用多環(huán)境配置時(shí)(如開(kāi)發(fā)、測(cè)試、生產(chǎn)環(huán)境),可以通過(guò)激活不同的profiles來(lái)加載對(duì)應(yīng)的配置文件。
到此這篇關(guān)于SpringBoot配置文件啟動(dòng)加載順序的方法步驟的文章就介紹到這了,更多相關(guān)SpringBoot配置文件啟動(dòng)加載順序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot無(wú)法加載yml配置文件的解決方案
- SpringBoot使用不同環(huán)境動(dòng)態(tài)加載不同配置文件
- SpringBoot配置文件的優(yōu)先級(jí)順序、加載順序、bootstrap.yml與application.yml區(qū)別及說(shuō)明
- SpringBoot項(xiàng)目部署時(shí)application.yml文件的加載優(yōu)先級(jí)和啟動(dòng)腳本問(wèn)題
- SpringBoot中的配置文件加載優(yōu)先級(jí)詳解
- SpringBoot加載不出來(lái)application.yml文件的解決方法
- SpringBoot項(xiàng)目加載配置文件的6種方式小結(jié)
- SpringBoot實(shí)現(xiàn)配置文件自動(dòng)加載和刷新的示例詳解
- SpringBoot的配置文件application.yml及加載順序詳解
- springboot加載配值文件的實(shí)現(xiàn)步驟
相關(guān)文章
使用SpringBoot Actuator監(jiān)控應(yīng)用示例
Actuator是Spring Boot提供的對(duì)應(yīng)用系統(tǒng)的自省和監(jiān)控的集成功能,可以對(duì)應(yīng)用系統(tǒng)進(jìn)行配置查看、相關(guān)功能統(tǒng)計(jì)等。這篇文章主要介紹了使用SpringBoot Actuator監(jiān)控應(yīng),有興趣的可以了解一下2018-05-05
使用Spring?Cloud?Stream處理事件的示例詳解
Spring?Cloud?Stream?是基于?Spring?Boot?的用于構(gòu)建消息驅(qū)動(dòng)微服務(wù)的框架,本文主要介紹了如何使用?Spring?Cloud?Stream?來(lái)處理事件,需要的可以參考一下2023-06-06
解決工具接口調(diào)用報(bào)錯(cuò):error:Unsupported Media Type問(wèn)題
當(dāng)遇到"UnsupportedMediaType"錯(cuò)誤時(shí),意味著HTTP請(qǐng)求的Content-Type與服務(wù)器期望的不匹配,比如服務(wù)器期待接收J(rèn)SON格式數(shù)據(jù),而發(fā)送了純文本格式,常見(jiàn)的Content-Type類(lèi)型包括text/html、application/json、multipart/form-data等2024-10-10
SpringBoot如何返回頁(yè)面的實(shí)現(xiàn)方法
SpringBoot中使用Controller和頁(yè)面的結(jié)合能夠很好地實(shí)現(xiàn)用戶(hù)的功能及頁(yè)面數(shù)據(jù)的傳遞。本文介紹了如何實(shí)現(xiàn)頁(yè)面的返回以及這里面所包含的坑,感興趣的可以了解一下2021-07-07
Java開(kāi)發(fā)常見(jiàn)錯(cuò)誤之?dāng)?shù)值計(jì)算精度和舍入問(wèn)題詳析
除了使用Double保存浮點(diǎn)數(shù)可能帶來(lái)精度問(wèn)題外,更匪夷所思的是這種精度問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于Java開(kāi)發(fā)常見(jiàn)錯(cuò)誤之?dāng)?shù)值計(jì)算精度和舍入問(wèn)題的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11
Java 動(dòng)態(tài)生成類(lèi)和實(shí)例, 并注入方法操作示例
這篇文章主要介紹了Java 動(dòng)態(tài)生成類(lèi)和實(shí)例, 并注入方法操作,結(jié)合實(shí)例形式分析了Java 動(dòng)態(tài)生成類(lèi)和實(shí)例以及動(dòng)態(tài)注入相關(guān)操作技巧,需要的朋友可以參考下2020-02-02
在IntelliJ?IDEA中配置SSH服務(wù)器開(kāi)發(fā)環(huán)境并實(shí)現(xiàn)固定地址遠(yuǎn)程連接的操作方法
本文主要介紹如何在IDEA中設(shè)置遠(yuǎn)程連接服務(wù)器開(kāi)發(fā)環(huán)境,并結(jié)合Cpolar內(nèi)網(wǎng)穿透工具實(shí)現(xiàn)無(wú)公網(wǎng)遠(yuǎn)程連接,然后實(shí)現(xiàn)遠(yuǎn)程Linux環(huán)境進(jìn)行開(kāi)發(fā),本例使用的是IDEA2023.2.5版本,感興趣的朋友跟隨小編一起看看吧2024-01-01
Maven項(xiàng)目如何查找jar包是由哪個(gè)依賴(lài)引入的
這篇文章主要介紹了Maven項(xiàng)目如何查找jar包是由哪個(gè)依賴(lài)引入的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Spring @async方法如何添加注解實(shí)現(xiàn)異步調(diào)用
這篇文章主要介紹了Spring @async方法如何添加注解實(shí)現(xiàn)異步調(diào)用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01

