【详细学习SpringBoot源码之属性配置文件加载原理(application.properties|application.yaml)-7】

06全局配置文件application.yaml详解 Spring Boot 提供了大量的自动配置,极大地简化了spring 应用的开发过程,当用户创建了一个 Spring Boot 项目后,即使不进行任何配置,该项目也能顺利的运行起来。当然,用户也可以根据自身的需要使用配置文件修改 Spring Boot 的默认设置。 SpringBoot 默认使用以下 2 种全局的配置文件,其文件名是固定的。 application.properties application.yml application.properties与 application.y.. 阅读详情

一.知识回顾

【0.SpringBoot专栏的相关文章都在这里哟,后续更多的文章内容可以点击查看】
【1.SpringBoot初识之Spring注解发展流程以及常用的Spring和SpringBoot注解】
【2.SpringBoot自动装配之SPI机制&SPI案例实操学习&SPI机制核心源码学习】
【3.详细学习SpringBoot自动装配原理分析之核心流程初解析-1】
【4.详细学习SpringBoot自动装配原理之自定义手写Starter案例实操实战-2】
【5.IDEA中集成SpringBoot源码环境详细步骤讲解】
【6.初识SpringBoot核心源码之SpringApplication构造器以及run方法主线流程-3】
【7.详细学习SpringBoot核心源码之SpringApplication构造器&Run方法源码详细流程-4】
【8.详细学习SpringBoot核心源码之监听器原理-5(观察者设计模式、初始化并加载监听器核心流程、事件的发布器核心流程、SpringBoot中默认的监听器以及默认的事件类型)】
【9.详细学习SpringBoot源码之自定义监听器实战演练-6(自定义监听器、自定义监听事件、指定监听事件)】

二.SpringBoot源码之属性文件加载原理(application.properties|application.yaml)

2.1 属性配置文件加载原理分析

在创建SpringBoot项目的时候会在对应的application.properties或者application.yml文件中添加对应的属性信息,我们的问题是这些属性文件是什么时候被加载的?如果要实现自定义的属性文件怎么来实现呢?

在这里插入图片描述

2.2 属性配置文件加载原理分析入口

结合我们前面介绍的SpringBoot中的监听事件机制,我们首先看下SpringApplication.run()方法,在该方法中会针对SpringBoot项目启动的不同的阶段来发布对应的事件。

在这里插入图片描述

application.properties配置文件加载的过程代码如下:

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
			ApplicationArguments applicationArguments) {
		// Create and configure the environment
		ConfigurableEnvironment environment = getOrCreateEnvironment();
		configureEnvironment(environment, applicationArguments.getSourceArgs());
		ConfigurationPropertySources.attach(environment);
		// 在配置环境信息之前发布事件
		listeners.environmentPrepared(environment);
		bindToSpringApplication(environment);
		if (!this.isCustomEnvironment) {
			environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
					deduceEnvironmentClass());
		}
		ConfigurationPropertySources.attach(environment);
		return environment;
	}

处理属性文件加载解析的监听器是 ConfigFileApplicationListener ,这个监听器监听的事件有两个。

在这里插入图片描述

  而我们进入SpringApplication.prepareEnvironment()方法中发布的事件其实就是ApplicationEnvironmentPreparedEvent事件。
在这里插入图片描述

进入方法listeners.environmentPrepared(environment);

在这里插入图片描述

进入定义listener.environmentPrepared(environment);接口的方法
在这里插入图片描述

继续进入会看到对应的发布事件:ApplicationEnvironmentPreparedEvent

在这里插入图片描述

在此处打一个断点,通过debug运行结果:在initialMulticaster中是有ConfigFileApplicationListener这个监听器的。如果再这个位置触发了配置环境的监听器,后续的逻辑就应该进入对应的逻辑实现方法。

image.png

三.SpringBoot源码之属性配置文件监听器-ConfigFileApplicationListener监听流程分析

3.1 ConfigFileApplicationListener监听流程分析

ConfigFileApplicationListener中具体的如何来处理配置文件的加载解析的。

在这里插入图片描述

如果是 ApplicationEnvironmentPreparedEvent则进入onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);方法
在这里插入图片描述

直接进入ConfigFileApplicationListener.postProcessEnvironment()方法。
在这里插入图片描述
进入实现类重写的方法
在这里插入图片描述

在进入addPropertySources()方法中会完成两个核心操作:

  1. 创建Loader对象
  2. 调用Loader对象的load方法
/**
	 * Add config file property sources to the specified environment.
	 * @param environment the environment to add source to
	 * @param resourceLoader the resource loader
	 * @see #addPostProcessors(ConfigurableApplicationContext)
	 */
	protected void addPropertySources(ConfigurableEnvironment environment, ResourceLoader resourceLoader) {
		RandomValuePropertySource.addToEnvironment(environment);
		// 创建Loader对象同时会完成属性加载器的加载 同时调用load方法
		new Loader(environment, resourceLoader).load();
	}

3.2 Loader构造器

在Loader构造器中执行了什么操作,最重要的就是加载解析配置文件。

在这里插入图片描述

通过源码我们可以发现在其中获取到了属性文件的加载器、从spring.factories文件中获取,对应的类型是 PropertySourceLoader类型。

# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
# 加载Properties配置文件
org.springframework.boot.env.PropertiesPropertySourceLoader,\
# 加载Yaml配置文件
org.springframework.boot.env.YamlPropertySourceLoader

在这里插入图片描述

并在loadFactories方法中会完成对象的实例化。

在这里插入图片描述

3.3 调用Loader对象的load方法

接下来学习load()方法的执行

void load() {
			FilteredPropertySource.apply(this.environment, DEFAULT_PROPERTIES, LOAD_FILTERED_PROPERTY,
					(defaultProperties) -> {
						// 创建默认的profile 链表
						this.profiles = new LinkedList<>();
						// 创建已经处理过的profile 类别
						this.processedProfiles = new LinkedList<>();
						// 默认设置为未激活
						this.activatedProfiles = false;
						// 创建loaded对象
						this.loaded = new LinkedHashMap<>();
						// 加载配置 profile 的信息,默认为 default
						initializeProfiles();
						// 遍历 Profiles,并加载解析
						while (!this.profiles.isEmpty()) {
							// 从双向链表中获取一个profile对象
							Profile profile = this.profiles.poll();
							// 非默认的就加入,进去看源码即可清楚
							if (isDefaultProfile(profile)) {
								addProfileToEnvironment(profile.getName());
							}
							load(profile, this::getPositiveProfileFilter,
									addToLoaded(MutablePropertySources::addLast, false));
							this.processedProfiles.add(profile);
						}
						// 解析 profile
						load(null, this::getNegativeProfileFilter, addToLoaded(MutablePropertySources::addFirst, true));
						// 加载默认的属性文件 application.properties
						addLoadedPropertySources();
						applyActiveProfiles(defaultProperties);
					});
		}

然后进入具体的apply()方法

static void apply(ConfigurableEnvironment environment, String propertySourceName, Set<String> filteredProperties,
			Consumer<PropertySource<?>> operation) {
		// 获取当前环境下的所有的资源加载器
		MutablePropertySources propertySources = environment.getPropertySources();
		// 根据propertySourceName从众多的加载器中获取对应的加载器 默认的没有
		PropertySource<?> original = propertySources.get(propertySourceName);
		if (original == null) {
			operation.accept(null);
			return;
		}
		propertySources.replace(propertySourceName, new FilteredPropertySource(original, filteredProperties));
		try {
			operation.accept(original);
		}
		finally {
			propertySources.replace(propertySourceName, original);
		}
	}

退出来,再次学习load主方法流程,然后进入load(null, this::getNegativeProfileFilter, addToLoaded(MutablePropertySources::addFirst, true));

private void load(Profile profile, DocumentFilterFactory filterFactory, DocumentConsumer consumer) {
			// 获得默认的扫描路径,如果没有特殊指定 ,
			// 就采用常量 DEFAULT_ SEARCH_ LOCATIONS中定义的4个路 径 。
			// 而getSearchNames 方 法获得的就是 application 这个默认的配置文件名。
			// 然后,逐一遍历加载目录路径及其指定文件名的文件。
			// file:./config/ file:./ classpath:/config/ classpath:/ 默认的四个路径
			getSearchLocations().forEach((location) -> {
				boolean isFolder = location.endsWith("/");
				// 去对应的路径下获取属性文件 默认的文件名称为 application
				Set<String> names = isFolder ? getSearchNames() : NO_SEARCH_NAMES;
				names.forEach((name) -> load(location, name, profile, filterFactory, consumer));
			});
		}

首先是getSearchLocations()方法,在该方法中会查询默认的会存放对应的配置文件的位置,如果没有自定义的话,路径就是 file:./config/ file:./ classpath:/config/ classpath:/ 这4个

private Set<String> getSearchLocations() {
			// 如果有自定义的路径就使用自定义的
			if (this.environment.containsProperty(CONFIG_LOCATION_PROPERTY)) {
				return getSearchLocations(CONFIG_LOCATION_PROPERTY);
			}
			// 否则使用默认的4个路径 file:./config/ file:./ classpath:/config/ classpath:/
			Set<String> locations = getSearchLocations(CONFIG_ADDITIONAL_LOCATION_PROPERTY);
			locations.addAll(
					asResolvedSet(ConfigFileApplicationListener.this.searchLocations, DEFAULT_SEARCH_LOCATIONS));
			return locations;
		}

进入getSearchLocations(String propertyName) 方法

private Set<String> getSearchLocations(String propertyName) {
			Set<String> locations = new LinkedHashSet<>();
			if (this.environment.containsProperty(propertyName)) {
				for (String path : asResolvedSet(this.environment.getProperty(propertyName), null)) {
					if (!path.contains("$")) {
						path = StringUtils.cleanPath(path);
						if (!ResourceUtils.isUrl(path)) {
							path = ResourceUtils.FILE_URL_PREFIX + path;
						}
					}
					locations.add(path);
				}
			}
			return locations;
		}

然后回到load方法中,遍历4个路径,然后加载对应的属性文件。

在这里插入图片描述

  getSearchNames()获取的是属性文件的名称。如果自定义了就加载自定义的

image.png

  否则加载默认的application文件。

image.png

再回到前面的方法

image.png

进入load方法,会通过前面的两个加载器来分别加载application.properties和application.yml的文件。

image.png
具体实现的代码

private void load(String location, String name, Profile profile, DocumentFilterFactory filterFactory,
				DocumentConsumer consumer) {
			if (!StringUtils.hasText(name)) {
				for (PropertySourceLoader loader : this.propertySourceLoaders) {
					if (canLoadFileExtension(loader, location)) {
						// 去对应的文件夹下加载属性文件 applicaiton.properties application.yml
						load(loader, location, profile, filterFactory.getDocumentFilter(profile), consumer);
						return;
					}
				}
				throw new IllegalStateException("File extension of config file location '" + location
						+ "' is not known to any PropertySourceLoader. If the location is meant to reference "
						+ "a directory, it must end in '/'");
			}
			Set<String> processed = new HashSet<>();
			// 获取properties和yml的资源加载器
			for (PropertySourceLoader loader : this.propertySourceLoaders) {
				// 获取对应的加载器加载的后缀 properties xml yml ymal
				for (String fileExtension : loader.getFileExtensions()) {
					if (processed.add(fileExtension)) {
						// 加载文件 application.properties application.xml
						// application.yml application.yaml
						loadForFileExtension(loader, location + name, "." + fileExtension, profile, filterFactory,
								consumer);
					}
				}
			}
		}

loader.getFileExtensions()获取对应的加载的文件的后缀。
在这里插入图片描述

image.png

image.png
然后退出进入loadForFileExtension方法
image.png

进入loadForFileExtension()方法,对profile和普通配置分别加载

private void loadForFileExtension(PropertySourceLoader loader, String prefix, String fileExtension,
				Profile profile, DocumentFilterFactory filterFactory, DocumentConsumer consumer) {
			DocumentFilter defaultFilter = filterFactory.getDocumentFilter(null);
			DocumentFilter profileFilter = filterFactory.getDocumentFilter(profile);
			if (profile != null) {
				// 如果有profile的情况比如 dev --> application-dev.properties
				String profileSpecificFile = prefix + "-" + profile + fileExtension;
				load(loader, profileSpecificFile, profile, defaultFilter, consumer);
				load(loader, profileSpecificFile, profile, profileFilter, consumer);
				// Try profile specific sections in files we've already processed
				for (Profile processedProfile : this.processedProfiles) {
					if (processedProfile != null) {
						String previouslyLoaded = prefix + "-" + processedProfile + fileExtension;
						load(loader, previouslyLoaded, profile, profileFilter, consumer);
					}
				}
			}
			// 加载正常的情况的属性文件 application.properties
			load(loader, prefix + fileExtension, profile, profileFilter, consumer);
		}

继续进入 load(loader, prefix + fileExtension, profile, profileFilter, consumer); 方法

private void load(PropertySourceLoader loader, String location, Profile profile, DocumentFilter filter,
				DocumentConsumer consumer) {
			try {
				Resource resource = this.resourceLoader.getResource(location);
				if (resource == null || !resource.exists()) {
					if (this.logger.isTraceEnabled()) {
						StringBuilder description = getDescription("Skipped missing config ", location, resource,
								profile);
						this.logger.trace(description);
					}
					return;
				}
				if (!StringUtils.hasText(StringUtils.getFilenameExtension(resource.getFilename()))) {
					if (this.logger.isTraceEnabled()) {
						StringBuilder description = getDescription("Skipped empty config extension ", location,
								resource, profile);
						this.logger.trace(description);
					}
					return;
				}
				String name = "applicationConfig: [" + location + "]";
				// 加载属性文件信息
				List<Document> documents = loadDocuments(loader, name, resource);
				if (CollectionUtils.isEmpty(documents)) {
					if (this.logger.isTraceEnabled()) {
						StringBuilder description = getDescription("Skipped unloaded config ", location, resource,
								profile);
						this.logger.trace(description);
					}
					return;
				}
				List<Document> loaded = new ArrayList<>();
				for (Document document : documents) {
					if (filter.match(document)) {
						addActiveProfiles(document.getActiveProfiles());
						addIncludedProfiles(document.getIncludeProfiles());
						loaded.add(document);
					}
				}
				Collections.reverse(loaded);
				if (!loaded.isEmpty()) {
					loaded.forEach((document) -> consumer.accept(profile, document));
					if (this.logger.isDebugEnabled()) {
						StringBuilder description = getDescription("Loaded config file ", location, resource, profile);
						this.logger.debug(description);
					}
				}
			}
			catch (Exception ex) {
				throw new IllegalStateException("Failed to load property source from location '" + location + "'", ex);
			}
		}

image.png

image.png

image.png

image.png

image.png

接下来我们就要开始加载我们存在的application.properties文件。

3.4 资源加载器是加载具体的文件信息(application.properties为例)

在找到了要加载的文件的名称和路径后,我们来看下资源加载器是如何来加载具体的文件信息的。

在这里插入图片描述

进入loadDocuments方法中,我们会发现会先从缓存中查找,如果缓存中没有则会通过对应的资源加载器来加载了。

image.png

此处是PropertiesPropertySourceLoader来加载的。当然如果我们使用的是yml配置文件的话,使用的就是YamlPropertySourceLoader。

image.png

image.png

进入loadProperties方法

image.png

之后进入load()方法看到的就是具体的加载解析properties文件中的内容了。
image.png

好了,关于【详细学习SpringBoot源码之属性配置文件加载原理(application.properties|application.yaml)-7】就先学习到这里,更多的内容持续学习创作中,敬请期待。

SpringBoot | 详解SpringBoot配置文件及其原理 目录 一、配置文件 二、YAML语法 1、基本语法 2、值的写法 (1)、字面量:普通的值(数字,字符串,布尔) (2)、对象、Map(属性和值) (3)、数组(List、Set) 三、配置文件值注入 1、一个简单的示例 2、@Value获取值和@ConfigurationProperties获取值比较 3、数据校验 4、使用@PropertySource加载指定的配... 阅读详情

相关推荐

Springboot配置文件加载源码解读

当我们使用spring.config.location加载指定的配置文件,就不会再使用上述默认的文件加载规则了,也就是说classpath:/,classpath:/config/,file:./,file:./config/*/,file:./config/路径下的配置文件都不会再加载了,经过查看源码发现,加载配置文件会先加载spring.config.additional-location配置且使用追加模式,不影响默认文件的加载,那么是不是将。就可以正常执行了,实验验证,猜测正确,使用。

weixin_50379618的博客 1241

SpringBoot加载配置文件原理分析

本文是基于SpringBoot2.4.0之前的版本分析的,2.4.0之后有所不同 想必大家对SpringBoot中的application.properties(或application.yaml)文件都是再熟悉不过的了。它是应用的配置文件,我们可以把需要的一些配置信息都写在这个文件里面,需要的时候,我们可以通过@Value注解来直接获取即可,那这个文件是什么时候以及如何被应该加载的呢?这一直是我之前疑惑的地方,也是终于有时间对这一部分进行了详细的源码分析。 原理先行 整个配置文件的加载过程其实就是一个.

ITlikeyou的博客 3699

SpringBoot系列之@PropertySource读取yaml文件

SpringBoot系列之@PropertySource支持yaml文件读取 最近在做实验,想通过@PropertySource注解读取配置文件的属性,进行映射,习惯上用properties都是测试没问题的,偶然换成yaml文件,发现都读取不到属性值 因为yaml语法很简洁,比较喜欢写yaml配置文件,很显然,@PropertySource默认不支持yaml读取,我们改成@Value注解也是可以读...

Nicky's blog 8508

SpringBoot全局配置文件加载原理详解(万字源码分析)

SpringBoot全局配置文件加载原理详解(源码分析) SpringBoot全局配置文件加载原理详解(源码分析)SpringBoot配置文件初见配置文件位置的优先级properties与yaml的优先级对比SpringBoot配置文件的加载原理源码分析加载ApplicationListener实现类监听器ConfigFileApplicationListener监听器监听ApplicationEnvironmentPreparedEvent事件发送事件与监听器的触发ApplicationStarting

大数据开发、JAVA开发、人工智能AI 2544

Python自动化神器:OP插件64位版从安装到实战(附雷电模拟器截图技巧)

本文详细介绍了Python自动化神器OP插件64位版的安装与实战应用,包括环境搭建、窗口控制、鼠标键盘模拟等核心功能。特别针对雷电模拟器提供了最小化截图技术和OCR识别优化方案,帮助开发者高效实现Windows自动化任务。

weixin_29094539的博客 330

Win10管理员权限的‘暗门’:从mmc.exe被阻止,聊聊UAC与自动提权那些事儿

本文深入解析Windows 10中UAC(用户账户控制)与自动提权机制,探讨mmc.exe被阻止的深层原因及解决方案。从UAC工作原理到自动提权机制,再到具体诊断与修复步骤,帮助用户理解并解决权限管理问题,同时平衡安全性与便利性。

weixin_30521161的博客 419

SpringBoot 常用的配置文件 application.yml和 bootstrap.yml的区别

SpringBoot默认支持properties和YAML两种格式的配置文件。前者格式简单,但是只支持键值对。如果需要表达列表,最好使用YAML格式。

Java+GO+JS全栈工程师-鹤冲天的博客:编程辅导~商务合作~技术交流 2547

Data+AI新玩法:Text2SQL让数据查询变得如此简单!

你是不是也遇到过这种情况?明明手头有海量数据,却因为SQL这道“门槛”,让分析和决策变得复杂和拖沓。你可能想着:“要是我能直接用自然语言和数据库对话,那该多好!你不是一个人在这样想,Text2SQL技术正是为了帮你摆脱这一困境而诞生的。

Ase5gqe的博客 865

SpringBoot2配置文件application.yaml

源码基于SpringBoot 2.4.4 1、认识配置文件 1.1 配置文件的加载 创建SpringBoot项目的时候,会自动创建一个application.properties文件,该文件是SpringBoot默认的配置文件。 SpringBoot在启动的时候会默认去寻找并加载application.properties文件和application.yaml文件,在以下路径中寻找: (1)classpath目录下 (2)classpath目录下的config文件夹 (3)项目根目录 (4)项目根目录下co

秃头哥编程 997

实战解析:利用Wireshark解密QQ通信协议

本文提供了一份利用Wireshark工具分析QQ通信协议的实战指南。文章详细介绍了从环境准备、捕获数据包到解析协议层的完整流程,重点演示了如何识别QQ号码字段、观察加密数据特征以及区分不同通信类型(如文本、文件传输)。通过此实践,读者可以深入理解网络分层模型和现代应用加密通信机制,提升网络协议分析与安全诊断能力。

weixin_29210727的博客 407

FPGA进位链(Carry Chain)实战:从Xilinx CARRY8原语到性能优化全解析

本文深入解析了FPGA进位链(Carry Chain)的原理与应用,重点剖析了Xilinx CARRY8原语的端口功能与内部机制。通过实测数据揭示了进位链的真实延迟特性与温度影响,并详细阐述了如何利用DI和S信号进行动态路径优化、实现减法运算与条件进位选择,从而有效提升设计性能。最后,文章探讨了系统级的流水线拆分、布局约束等实战优化策略与常见陷阱。

weixin_29313817的博客 449

SpringBoot application.yml/.properties配置文件加载过程

参考:Springboot源码之application.yaml读取过程 SpringBoot配置文件一般为application.yml或application.property等,其加载流程在SpringApplication的run()方法中的ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);中完成,当环境准备好会触发EventPublishingRunListener i

weixin_41866717的博客 2442

【GNSS测试技术(一)】GNSS基础原理介绍

GNSS(全球卫星导航系统)是一种基于卫星信号的定位技术,通过使用分布在地球轨道上的卫星,为用户提供全球范围内的定位、导航和授时服务。

新猿异码的博客 5751

SpringBoot 的配置文件 application.properties的位置问题&&文件问题

在SpringBoot中,很神奇的事,不管是tomcat等服务器,还是mysql等数据库,还是其他一些配置可以在application.properties中进行配置,而使用默认的时候,也就是新建项目的时候,application.properties是在resources资源文件下的,无需做其他的事,你只有按这么写就可以生效,但是我还没开始看源码,所以心里不是很靠谱,后面还自己去看看。 在 Sp...

qq_37432174的博客 2324

ICM20948 DMP代码详解(69)

ICM20948 DMP代码详解(69)

phmatthaus的专栏 615

【Simulink教程案例19】基于simulink的扩频通信系统建模与仿真

扩频是一种应用于数字调制信号的调制技术,可以提高传输信号的带宽。扩频通信具有抗干扰能力强,扩频增益越大,抗干扰能力越强。而且扩频通信具有很强的保密性,扩频后信号近似白噪声,功率谱密度也很低。扩频通信可用于多址通信。扩频调制有如下三个特点:① 扩频后信号的带宽远大于信号所需的带宽② 使用扩频码进行扩频调制,扩频码与信号中的数据相互独立③ 在接收端,通过将接收信号与扩频码的同步副本进行相关,实现解扩。

FPGA/MATLAB学习教程/源码/项目合作开发 2197

【SpringBoot】18张图,详解SpringBoot解析yml全流程

前几天的时候,项目里有一个需求,需要一个开关控制代码中是否执行一段逻辑,于是理所当然的在 yml 文件中配置了一个属性作为开关,再配合 nacos 就可以随时改变这个值达到我们的目的,yml文件中是这样写的

阿Q的小窝 8590

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

SpringBoot读取application.properties中文乱码的解决办法

1.问题描述 由于ye

qq_34644183的博客 1万+

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Spring boot源码深入学习(五) | 准备环境时application配置文件的加载优先级

回顾 上一篇写到springboot中准备环境prepareEnvironment的实现逻辑,下面着重学习一下application.properties或者application.yaml的加载顺序 正文 由图可知,我们可以看到,会从4个路径下面分别去加载配置文件。下面我写了一个demo,看一下各个位置的加载优先级。 优先级从高到低依次为 file:./config/ :项目根目录找config文件夹下找配置文件。图中:端口1111 file:./ :根目录下找配置文件。图中:端口2222 ==clas

qq_38425803的博客 1091

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

springboot启动时是如何加载配置文件application.yml文件

注:这篇文章是为了解决配置文件找不到而写的,是为了解决问题而写的,主要是解析查找配置文件路径的过程,具体的解析配置文件的过程,读者可以细看源码,最后我也找到了配置文件为什么找不到的原因,主要是因为idea编译时,classpath路径下面没有application.yml文件,复制配置文件到classpath目录下,问题就解决了!默认先读取的是location,然后是配置文件的名字“application”,最后才是文件类型“properties”或者“yml”;

web17535224648的博客 3147

SpringBoot源码分析-启动时如何加载application.yml

SpringBoot启动如何加载application.yml配置文件

qq_27579471的博客 1354

SpringBoot配置文件类型:properties与yml格式对比源码级分析(7)

在SpringBoot应用中,配置文件是非常重要的组成部分,它负责存储应用运行时需要的各种配置信息,如数据库连接信息、服务器端口、日志级别等。通过配置文件,开发者可以在不修改代码的情况下,动态调整应用的行为,提高了应用的灵活性和可维护性。

Android开发领域创作者 893

springboot environment对象之application文件加载源码解析

前言 首先我们都知道springboot的约定大于配置的一条约定就是classpath下指定application.properties或者yaml文件的配置文件会被加载到spring中作为配置文件 那么在springboot中它是如何加载的呢?本文就是从源码介绍application文件的加载 源码解析 从springboot启动类入手 SpringApplication.run(ProvideApplication.class, args) public static ConfigurableAppl

qq_31086797的博客 1338

SpringBoot2.X基础教程:配置文件详解

SpringBoot2.X基础教程:配置文件详解

java程序鱼的博客 2764

Spring Boot application 配置文件加载源码解析:从 application.yml 到 PropertySource 的完整链路

本文基于 doocs/source-code-hunter 仓库中的 [SpringBoot-application-load.md](https://link.gitcode.com/i/5611223531975b863dcad0cc03b29319) 一文,以源码追踪的方式还原 Spring Boot 启动时 `application.yml` / `application.properti

gitblog_01146的博客 315

ESP32-C3 DNS广告拦截器:5字节哈希与原子替换背后的4个隐藏细节

esp32-c3-adblock 是一台 Pi-hole 风格 DNS 广告拦截器:把 53.7 万个广告域名的 40 位 FNV-1a 哈希(哈希=给内容算指纹,这里只保留 40 位)存进 flash,靠二分查找拦截,全程只用约 50 KB RAM。2 美元的 ESP32-C3,不带 PSRAM,扛住了这些。 问题是:一个没有 RAM 余量的芯片,凭什么把 14 万条黑名单装进去,还能在线换新

gitblog_01050的博客 378
上一篇: 【LeetCode每日一题:2011. 执行操作后的变量值~~~模拟】
下一篇: 【LeetCode每日一题:1754. 构造字典序最大的合并字符串~~~双指针+贪心算法】
硕风和炜
硕风和炜 优质创作者: Java技术领域 优质创作者: Java技术领域
博客等级 码龄7年 2万+粉丝 1024原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

硕风和炜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值