【springboot配置文件加载源码分析】

在Spring Boot的源码中,配置文件的加载是在应用程序启动的早期阶段进行的。具体来说,配置文件加载的主要步骤发生在SpringApplication类的run()方法中的prepareEnvironment方法中,真正读取我们的配置文件还是PropertySourceLoader。

本篇博客适合准备看源码,和想了解配置文件加载大体逻辑的同学。
本篇文章主要粘贴了加载配置文件的主要处理逻辑的源码,方便各位同学直接定位关键代码,辅助大家了解配置文件被处理的过程。

以下是Spring Boot源码中加载配置文件的主要步骤:

  1. prepareEnvironment()方法: 应用程序的入口点是SpringApplication类的run(),加载配置的方法入口run()中调用的prepareEnvironment()方法。初始化environment对象用于后续存储环境信息,以及后续处理逻辑的入口都在这个方法。

  2. ApplicationEnvironmentPreparedEvent 事件: 发布环境准备事件,通过spring事件发布机制去处理环境对象。关键代码 listeners.environmentPrepared(bootstrapContext, environment);

    private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {// Create and configure the environmentConfigurableEnvironment environment = getOrCreateEnvironment();configureEnvironment(environment, applicationArguments.getSourceArgs());ConfigurationPropertySources.attach(environment);//本行代码是解析配置的核心代码listeners.environmentPrepared(bootstrapContext, environment);DefaultPropertiesPropertySource.moveToEnd(environment);configureAdditionalProfiles(environment);bindToSpringApplication(environment);if (!this.isCustomEnvironment) {environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,deduceEnvironmentClass());}ConfigurationPropertySources.attach(environment);return environment;}
    

    这行代码我们继续debug的话会发现,核心逻辑就是发布了一个ApplicationEnvironmentPreparedEvent事件,通过debug可以发现有以下7个监听器对该事件做了监听。虽然有7个监听器,从类名上看我肯定是重点关注EnvironmentPostPorcessorApplicationListener
    在这里插入图片描述

  3. EnvironmentPostProcessor接口:我们继续跟踪EnvironmentPostPorcessorApplicationListener监听器的主要处理逻辑会发现,该监听器的逻辑主要是调用用EnvironmentPostProcessor接口。直接上代码 EnvironmentPostProcessorApplicationListener.onApplicationEnvironmentPreparedEvent

    private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {ConfigurableEnvironment environment = event.getEnvironment();SpringApplication application = event.getSpringApplication();for (EnvironmentPostProcessor postProcessor : getEnvironmentPostProcessors(event.getBootstrapContext())) {postProcessor.postProcessEnvironment(environment, application);}
    }
    

    可以看到上面代码主要就是遍历EnvironmentPostProcessor接口并执行postProcessEnvironment方法,这个地方会遍历哪些接口,大家就自行打断点吧,关键的处理器为ConfigDataEnvironmentPostProcessor这个接口postProcessEnvironment方法实现比较复杂,核心逻辑都在里面,分析到里面的方法我已经不行了。

    这个地方所遍历接口,也是springboot通过其SPI机制,在初始化SpringApplication时set进去的

  4. load()方法:通过我们不断的debug postProcessEnvironment方法,好像找到加载配置文件的主线了,load方法一看名字就是我们重点关注的对象!!!

    下面是postProcessEnvironment到load的调用栈信息: 在这里插入图片描述
    看一下load方法吧(下面代码有注释哦!):

    	public ConfigData load(ConfigDataLoaderContext context, StandardConfigDataResource resource)throws IOException, ConfigDataNotFoundException {if (resource.isEmptyDirectory()) {return ConfigData.EMPTY;}ConfigDataResourceNotFoundException.throwIfDoesNotExist(resource, resource.getResource());StandardConfigDataReference reference = resource.getReference();Resource originTrackedResource = OriginTrackedResource.of(resource.getResource(),Origin.from(reference.getConfigDataLocation()));String name = String.format("Config resource '%s' via location '%s'", resource,reference.getConfigDataLocation());//获取properties,yml加载器,加载对应的资源生成propertySources,封装成ConfigDataList<PropertySource<?>> propertySources = reference.getPropertySourceLoader().load(name, originTrackedResource);return new ConfigData(propertySources);}
    

关键代码就暂时分析到这儿,当前中间还有很多的逻辑,目前能力有限暂时到这儿,后续也会对该篇博客持续更新!!!!

总结一下吧

发布ApplicationEnvironmentPreparedEvent 事件进行一系列的处理,EnvironmentPostPorcessorApplicationListener监听处理器,调用EnvironmentPostProcessor接口处理环境加载配置,关键的接口实现是ConfigDataEnvironmentPostProcessor类去处理,最后是读取我们本地资源,根据不同的配置文件找到对应的PropertySourceLoader去加载我们
的properties,yaml 得到PropertySource,然后最后经过层层的封装,最后还是会放到environment中

问题遗留:配置文件优先级、远程配置如何加载的源码体现,后面再补充

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/319814.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++-赋值-string字符串类-函数

赋值 1&#xff09;通常编程中使用进行赋值操作&#xff0c;C增加了一些新的赋值语法。 #include <iostream>using namespace std;int main() {int a 1;//普通模式int b(2);//int b2;int c(a);//int c a;int d(ab);//int dab;cout <<"a" << a &…

如何下载和安装 Eclipse?

1.进入官网。Eclipse的官网地址为https://www.eclipse.org/。 2.在官网首页&#xff0c;点击“Download”按钮进入下载界面。 3.查找自己需要的 Eclipse 对应的版本。Eclipse有着多个版本&#xff0c;每个版本都有自己特定的用途和功能&#xff0c;主要包括以下版本&#xff1…

JSON网络令牌JWT

1.什么是身份验证 日常生活中的身份验证的场景: 比如进入公司的大楼时&#xff0c;需要携带工牌&#xff1b;打卡上班时&#xff0c;需要指纹识别&#xff1b;打开工作电脑时&#xff0c;需要输入密码。 2. 什么是 JSON 网络令牌&#xff1f; JSON Web Token (JWT) 是一个开…

PostgreSQL 分区

由于大量数据存储在数据库同一张表中&#xff0c;后期性能和扩展会受到影响。所以需要进行表分区&#xff0c;因为它可以将大表分成较小的表&#xff0c;从而减少内存交换问题和表扫描&#xff0c;最终提高性能。庞大的数据集被分成更小的分区&#xff0c;更易于访问和管理。 …

【设计模式之美】面向对象分析方法论与实现(二):需求到接口实现的方法论

文章目录 一. 进行面向对象设计1. 划分职责>需要有哪些类2. 定义类及其属性和方法3. 定义类与类之间的交互关系4. 将类组装起来并提供执行入口 二. 如何进行面向对象编程&#xff1f;1. 接口实现2. 辩证思考与灵活应用 【设计模式之美】面向对象分析方法论与实现&#xff08…

(vue)el-popover鼠标移入提示效果

(vue)el-popover鼠标移入提示效果 效果&#xff1a; 代码&#xff1a; <el-form-itemv-for"(item,index) of ele.algorithmParameters":key"index":label"item.parametersName"class"descInput" ><el-input v-model"i…

linux centos 添加临时ip

### 1.添加ip ip addr add IP/mask dev 网络设备 例&#xff1a;ip addr add 172.104.210.247/24 dev ens5f1 ### 2.启动网卡 ip link set up 网络设备 例&#xff1a;ip link set up ens3f0 ### 3.设置默认路由 ip route add default via GATEWAY 例&#xff1a;ip route add …

Eureka服务端

一般我们Server端会像下图一样&#xff0c;引入Eureka&#xff0c;下面就通过这个来分析Eureka服务端源码流程 一、服务端配置 EnableEurekaServer会引入EurekaServerMarkerConfiguration类 EurekaSeverMarkerConfiguration最终会引入Marker对象&#xff0c;这就是一个标记…

JavaScript中location对象使用【详解】

✨前言✨   本篇文章主要在于&#xff0c;了解并会使用JavaScript中location对象 &#x1f352;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f352;博主将持续更新学习记录收获&#xff0c;友友们有任何问题可以在评论区留言 &…

CNN——AlexNet

1.AlexNet概述 论文原文&#xff1a;ImageNet Classification with Deep Convolutional Neural Networks 在LeNet提出后&#xff0c;卷积神经网络在计算机视觉和机器学习领域中很有名气。但卷积神经网络并没有主导这些领域。这是因为虽然LeNet在小数据集上取得了很好的效果&am…

二叉树链式结构的实现(二叉树的遍历以及各种常用功能函数的实现)

之前也是把堆部分的知识点梳理完毕&#xff08;即二叉树链式顺序的实现&#xff09;&#xff1a;堆的应用&#xff1a;堆排序和TOP-K问题 那么讲完了二叉树链式结构的实现。今天就进入二叉树链式结构的实现&#xff1a; 文章目录 1.准备工作2.二叉树的遍历2.1前序遍历2.2中序遍…

【C语言】程序练习(四)

大家好&#xff0c;这里是争做图书馆扫地僧的小白。非常感谢各位的支持&#xff0c;也期待着您的关注。 目前博主有着C语言、C、linux以及数据结构的专栏&#xff0c;内容正在逐步的更新。 希望对各位朋友有所帮助同时也期望可以得到各位的支持&#xff0c;有任何问题欢迎私信与…