springboot加載配值文件的實(shí)現(xiàn)步驟
Spring Boot 加載配置文件的機(jī)制是其核心功能之一,它通過(guò)一系列源碼實(shí)現(xiàn)從不同來(lái)源加載配置,并支持靈活的配置管理。以下是 Spring Boot 加載配置文件的源碼解析及其實(shí)現(xiàn)原理的詳細(xì)說(shuō)明。(下述兩段是加載配置文件的源碼片段)
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.sources = new LinkedHashSet();
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = Collections.emptySet();
this.isCustomEnvironment = false;
this.lazyInitialization = false;
this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
this.applicationStartup = ApplicationStartup.DEFAULT;
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
//1.推測(cè)web應(yīng)用類型(NONE REACTIVE SERVLET)
this.webApplicationType = WebApplicationType.deduceFromClasspath();
//2.從spring.factories中獲取BootstrapRegistryInitializer對(duì)象
this.bootstrapRegistryInitializers =
this.getBootstrapRegistryInitializersFromSpringFactories();
//3.從spring.factories中獲取ApplicationContextInitializer對(duì)象
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
//4.從spring.factories中獲取ApplicationListener對(duì)象
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
//5.推測(cè)出Main類 (main()方法所在的類)
this.mainApplicationClass = this.deduceMainApplicationClass();
}public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
ConfigurableApplicationContext context = null;
this.configureHeadlessProperty();
/**從spring.factories中獲取SpringApplicationRunListeners 對(duì)象
* 默認(rèn)會(huì)拿到一個(gè)EventPublishingRunListener ,他會(huì)啟動(dòng)過(guò)程的各個(gè)階段發(fā)布對(duì)應(yīng)的事件
**/
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
//將run()的參數(shù)封裝為DefaultApplicationArguments對(duì)象
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//配置文件的入口
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
this.configureIgnoreBeanInfo(environment);
Banner printedBanner = this.printBanner(environment);
//根據(jù)應(yīng)用類型創(chuàng)建Spring容器
context = this.createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
//刷新Spring容器, 會(huì)解析配置類 掃描 啟動(dòng)Webserver
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
//調(diào)用applicationArguments 和CommandLineRunner
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
1. Spring Boot 加載配置文件的整體流程
Spring Boot 加載配置文件的流程可以分為以下幾個(gè)步驟:
初始化
Environment:在應(yīng)用啟動(dòng)時(shí),創(chuàng)建并初始化Environment對(duì)象。加載默認(rèn)配置文件:從
application.properties或application.yml加載配置。加載 Profile 特定的配置文件:根據(jù)激活的 Profile 加載
application-{profile}.properties或application-{profile}.yml。加載外部化配置:從命令行參數(shù)、環(huán)境變量、JNDI 等外部來(lái)源加載配置。
合并配置:將所有配置來(lái)源合并到
Environment中,供應(yīng)用程序使用。
2. 源碼解析
以下是 Spring Boot 加載配置文件的核心源碼解析。
2.1 SpringApplication.run()
Spring Boot 應(yīng)用的啟動(dòng)入口是 SpringApplication.run() 方法。在這個(gè)方法中,會(huì)初始化 Environment 并加載配置文件。
源碼位置:org.springframework.boot.SpringApplication
public ConfigurableApplicationContext run(String... args) {
// ...
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
// ...
}說(shuō)明:
prepareEnvironment()方法負(fù)責(zé)創(chuàng)建和配置Environment對(duì)象。
2.2 prepareEnvironment()
prepareEnvironment() 方法會(huì)調(diào)用 configureEnvironment() 來(lái)加載配置文件。
源碼位置:org.springframework.boot.SpringApplication
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {
// 創(chuàng)建 Environment 對(duì)象
ConfigurableEnvironment environment = getOrCreateEnvironment();
// 配置 Environment,加載配置文件
configureEnvironment(environment, applicationArguments.getSourceArgs());
// 觸發(fā)環(huán)境準(zhǔn)備事件
listeners.environmentPrepared(environment);
// 將 Environment 綁定到 SpringApplication
bindToSpringApplication(environment);
return environment;
}說(shuō)明:
getOrCreateEnvironment():根據(jù)應(yīng)用類型(Web 或非 Web)創(chuàng)建StandardEnvironment或StandardServletEnvironment。configureEnvironment():加載配置文件和其他外部化配置。
2.3 configureEnvironment()
configureEnvironment() 方法會(huì)調(diào)用 configurePropertySources() 和 configureProfiles() 來(lái)加載配置文件和激活 Profile。
源碼位置:org.springframework.boot.SpringApplication
protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
configurePropertySources(environment, args);
configureProfiles(environment, args);
}說(shuō)明:
configurePropertySources():加載命令行參數(shù)、默認(rèn)配置文件等。configureProfiles():設(shè)置激活的 Profile。
2.4 ConfigFileApplicationListener
ConfigFileApplicationListener 是 Spring Boot 加載配置文件的核心類。它監(jiān)聽(tīng) ApplicationEnvironmentPreparedEvent 事件,并加載 application.properties 或 application.yml 文件。
源碼位置:org.springframework.boot.context.config.ConfigFileApplicationListener
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationEnvironmentPreparedEvent) {
onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
}
}說(shuō)明:
onApplicationEnvironmentPreparedEvent():在環(huán)境準(zhǔn)備完成后觸發(fā),加載配置文件。
2.5 Loader.load()
Loader 是 ConfigFileApplicationListener 的內(nèi)部類,負(fù)責(zé)實(shí)際加載配置文件。
源碼位置:org.springframework.boot.context.config.ConfigFileApplicationListener.Loader
void load() {
for (String location : getSearchLocations()) {
for (String name : getSearchNames()) {
load(location, name);
}
}
}說(shuō)明:
getSearchLocations():獲取配置文件的搜索路徑(如classpath:/、file:./config/等)。getSearchNames():獲取配置文件的名稱(如application)。load(location, name):從指定路徑加載配置文件。
2.6 PropertySourcesLoader
PropertySourcesLoader 負(fù)責(zé)將配置文件內(nèi)容加載到 PropertySource 中。
源碼位置:org.springframework.boot.env.PropertySourcesLoader
public PropertySource<?> load(Resource resource) throws IOException {
if (resource.getFilename().endsWith(".yml")) {
return loadYaml(resource);
} else {
return loadProperties(resource);
}
}說(shuō)明:
loadYaml():加載 YAML 格式的配置文件。loadProperties():加載 Properties 格式的配置文件。
2.7 Profile 的加載
Spring Boot 支持通過(guò) Profile 加載不同的配置文件。Profiles 和 ProfilePropertySource 負(fù)責(zé)處理 Profile 相關(guān)的配置。
源碼位置:org.springframework.core.env.Profiles
public static Profiles of(String... profiles) {
return new Profiles() {
@Override
public boolean matches(Predicate<String> predicate) {
// ...
}
};
}說(shuō)明:
Profiles:管理 Profile 的激活狀態(tài)。ProfilePropertySource:根據(jù)激活的 Profile 加載特定的配置文件。
3.Spring Boot配置文件的實(shí)現(xiàn)原理
Spring Boot 加載配置文件的實(shí)現(xiàn)原理可以總結(jié)為以下幾點(diǎn):
- 多來(lái)源加載:支持從類路徑、外部目錄、環(huán)境變量、命令行參數(shù)等多種來(lái)源加載配置。
- 優(yōu)先級(jí)機(jī)制:后加載的配置會(huì)覆蓋先加載的配置,命令行參數(shù)的優(yōu)先級(jí)最高。
- Profile 支持:通過(guò)
spring.profiles.active指定激活的 Profile,加載對(duì)應(yīng)的配置文件。 - 外部化配置:支持從外部文件、環(huán)境變量、JNDI 等加載配置,適用于云原生和容器化部署。
4. 示例:Spring Boot 加載配置文件的流程
以下是一個(gè)完整的示例,展示 Spring Boot 如何加載配置文件。
4.1 默認(rèn)配置文件
application.properties:
server.port=8080 spring.profiles.active=dev
4.2 Profile 特定的配置文件
application-dev.properties:
server.port=8081
4.3 Java 代碼
@RestController
public class MyController {
?
@Value("${server.port}")
private String port;
?
@GetMapping("/port")
public String getPort() {
return "Server port: " + port;
}
}4.4 運(yùn)行結(jié)果
如果激活的 Profile 是
dev,則server.port的值為8081。如果沒(méi)有激活 Profile,則
server.port的值為8080。
5. 總結(jié)
Spring Boot 加載配置文件的機(jī)制非常靈活,支持多來(lái)源、多格式的配置加載。通過(guò) Environment、PropertySource、ConfigFileApplicationListener 等核心類和組件,Spring Boot 實(shí)現(xiàn)了配置文件的加載、合并和優(yōu)先級(jí)管理。理解這些源碼和機(jī)制,可以幫助我們更好地使用和擴(kuò)展 Spring Boot 的配置功能。
到此這篇關(guān)于springboot加載配值文件的實(shí)現(xiàn)步驟的文章就介紹到這了,更多相關(guān)springboot加載配值文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot無(wú)法加載yml配置文件的解決方案
- SpringBoot使用不同環(huán)境動(dòng)態(tài)加載不同配置文件
- SpringBoot配置文件啟動(dòng)加載順序的方法步驟
- 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及加載順序詳解
相關(guān)文章
Spring Boot中的那些條件判斷的實(shí)現(xiàn)方法
這篇文章主要介紹了Spring Boot中的那些條件判斷的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
Java結(jié)合redistemplate使用分布式鎖案例講解
在Java中使用RedisTemplate結(jié)合Redis來(lái)實(shí)現(xiàn)分布式鎖是一種常見(jiàn)的做法,特別適用于微服務(wù)架構(gòu)或多實(shí)例部署的應(yīng)用程序中,以確保數(shù)據(jù)的一致性和避免競(jìng)態(tài)條件,下面給大家分享使用Spring Boot和RedisTemplate實(shí)現(xiàn)分布式鎖的案例,感興趣的朋友一起看看吧2024-08-08
Spring ApplicationContextAware 接口的作用及使用方式
Spring提供了許多回調(diào)接口,用于Bean生命周期中執(zhí)行特定的操作,通過(guò)實(shí)現(xiàn)ApplicationContextAware接口,Spring提供了一種便捷的方式讓 Bean獲取對(duì)Spring容器的引用,本文介紹ApplicationContextAware接口的作用、使用方式,以及在實(shí)際應(yīng)用中的常見(jiàn)場(chǎng)景,感興趣的朋友一起看看吧2024-01-01
IntelliJ?IDEA?代碼運(yùn)行時(shí)中文出現(xiàn)亂碼問(wèn)題及解決方法
在我們剛接觸到IDEA時(shí),想美滋滋的敲一個(gè)“hello?world”來(lái)問(wèn)候這個(gè)世界,但難免會(huì)遇到這種問(wèn)題亂碼,這篇文章主要介紹了解決IntelliJ?IDEA?代碼運(yùn)行時(shí)中文出現(xiàn)亂碼問(wèn)題,需要的朋友可以參考下2023-09-09
Java兩整數(shù)相除向上取整的方式詳解(Math.ceil())
在調(diào)外部接口獲取列表數(shù)據(jù)時(shí),需要判斷是否已經(jīng)取完了所有的值,因此需要用到向上取整,下面這篇文章主要給大家介紹了關(guān)于Java兩整數(shù)相除向上取整的相關(guān)資料,需要的朋友可以參考下2022-06-06

