SpringBoot读取配置文件顺序

文章目录

  • 一、前言
  • 二、SpringBoot配置文件目录读取顺序
    • 源码解析
  • 三、SpringBoot配置文件类型读取顺序
    • 源码解析

一、前言

本文通过源码分析 SpringBoot 加载配置文件目录的顺序,以及 properties、xml、yml、yaml文件的读取顺序

二、SpringBoot配置文件目录读取顺序

配置文件目录读取顺序(由高到低):

  1. file:./config/ 当前项目下的/config目录
  2. file:./ 当前项目的根目录
  3. classpath:/config/ classpath的/config目录
  4. classpath:/ classpath的根目录

源码解析

我们从 SpringApplication.run 开始,一直往里走,来到 run(java.lang.String...) 方法,如下

image-20230727153319679

加载配置文件属于准备环境,我们继续跟进 prepareEnvironment 方法

image-20230727153442043

这里在环境准备就绪之后,会触发 environmentPrepared 事件,我们跟进 listeners.environmentPrepared(environment); 方法

image-20230727153847555

这里循环了所有的 SpringApplicationRunListener 调用其 environmentPrepared 方法,这个 listeners 其实就是读取 META-INF 目录下的 spring.factories 文件里的 org.springframework.boot.SpringApplicationRunListener,见下图

image-20230727154750488

ps:这里其实也是一个扩展点,如果你需要在环境准备就绪后,做一些自定义的操作,就可以自己写个类实现 SpringApplicationRunListener 接口,然后在自己的项目 /META-INF 目录下创建一个名为 spring.factories 的文件,在文件中添加 org.springframework.boot.SpringApplicationRunListener=自定义类的全路径

扯回来,我们知道这里的 listeners 其实就是 EventPublishingRunListener (见图),继续跟进其 environmentPrepared 方法

image-20230727155553838

这里调用了 Spring 的事件广播器去做事件广播,注意这里事件类是 ApplicationEnvironmentPreparedEvent 后面有用,继续跟进 multicastEvent 方法

image-20230727155759283

这里就是 Spring 事件广播的标准写法了,根据 event 找到匹配的 ApplicationListener,调用 invokeListener 方法,进去再调用 doInvokeListener 方法,最后会调用到 ApplicationListeneronApplicationEvent 方法,具体怎么找到这些 ApplicationListener 的,这里就不展开了,在众多匹配的 ApplicationListener 里有一个 ConfigFileApplicationListener ,看名字就知道,专门用来处理配置文件的,我们看它的 onApplicationEvent 方法

image-20230727162005026

上面我们知道事件类是 ApplicationEnvironmentPreparedEvent,所以这里走的是 onApplicationEnvironmentPreparedEvent 方法,继续跟进

image-20230727164746928

这里又从 spring.factories 文件里获取了 org.springframework.boot.env.EnvironmentPostProcessor,并且把自己(ConfigFileApplicationListener)也算进去了,因为 ConfigFileApplicationListener 也实现了 EnvironmentPostProcessor 接口,然后执行了这些 EnvironmentPostProcessorpostProcessEnvironment 方法,我们这里还是重点看 ConfigFileApplicationListenerpostProcessEnvironment 方法

image-20230727165041251

继续跟进 addPropertySources 方法

image-20230727165120996

继续跟进 load 方法

image-20230727170624833

这个方法里 initializeProfiles 方法会根据 spring.profiles.active 配置来决定加载哪个配置文件,如果没有就用 spring.profiles.default 配置,如果配的是 dev,就加载 application-dev.propertiesapplication-dev.yml 这样的配置文件,如果这两个参数都没有配,就加载 application.propertiesapplication.yml 这样的配置文件,下面具体看加载的逻辑里是如何获取目录的,跟进 load 方法

image-20230727174057481

很明显了,获取扫描目录的代码在 getSearchLocations 方法里

image-20230727174159191

可以看到返回值正是这4个目录,这个值一般都是取自 DEFAULT_SEARCH_LOCATIONS 这个常量,我们看下

image-20230727174326837

这里需要注意,这个常量是按优先级从低到高倒序排列的。

三、SpringBoot配置文件类型读取顺序

配置文件类型读取顺序(由高到低):

  1. properties
  2. xml
  3. yml
  4. yaml

源码解析

在上面我们讲到获取目录,下面就是要循环每个目录,在每个目录下找配置文件了,那么配置文件类型有好几种,读取的先后顺序是怎样的呢,我们先找到 load 方法

image-20230727175410839

可以看到循环中又调用了 load 方法,跟进

image-20230727175912993

可以看到走进了一个双层嵌套循环,循环调用了 loadForFileExtension 方法,方法里就是具体加载文件的源码了,我们这里重点关注的是文件类型的读取顺序,就不深究加载文件的源码了,我们看这个双层嵌套的循环,分别循环的是什么,先是循环的 propertySourceLoaders,然后再循环 loader 的 getFileExtensions 方法返回的 String 数组,这个 propertySourceLoaders 是什么呢,我们发现又又是读取的 spring.factories 文件,这回读的是 org.springframework.boot.env.PropertySourceLoader,在文件的最上面

image-20230727180524129

可以看到先后顺序是 PropertiesPropertySourceLoaderYamlPropertySourceLoader,我们再分别看这两个 loader 的 getFileExtensions 方法

image-20230727180709878

image-20230727180800564

结论很明显了,顺序是 properties > xml > yml > yaml。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

传统计算机视觉

传统计算机视觉 计算机视觉难点图像分割基于主动轮廓的图像分割基于水平集的图像分割交互式图像分割基于模型的运动分割 目标跟踪基于光流的点目标跟踪基于均值漂移的块目标跟踪基于粒子滤波的目标跟踪基于核相关滤波的目标跟踪 目标检测一般目标检测识别之特征一般目标检测识别…

绕过TLS/akamai指纹护盾

文章目录 前言TLS指纹什么是TLS指纹测试TLS指纹绕过TLS指纹使用原生urllib使用其他成熟库!!修改requests底层代码 Akamai指纹相关(HTTP/2指纹)什么是Akamai指纹测试Akamai指纹绕过Akamai指纹使用其他成熟库 实操参考 前言 有道是…

linux下有关mysql安装和登录的一些问题记录

1. 如何得知linux系统的版本信息,并选择对应兼容的MySQL? 终端输入命令如下: uname -srm 例如,得到版本信息:Linux 4.4.0-184-generic x86_64 相应地对系统版本信息分析如下: Linux系统版本是4.4.0-18…

华为openGauss数据库入门 - gsql用法

目录 1.1 gsql的语法 1.2 gsql常用选项 1.2.1 最常用的必要选项 1.2.2 -r选项 1.2.3 -E选项 1.2.4 -t选项 1.2.5 -A选项 1.2.6 -v选项 1.2.7 -c选项 1.2.8 -f选项 1.2.9 -q选项 1.3 gsql的元命令 1.3.1 \l命令 1.3.2 \du命令和\dg命令 1.3.3 \db命令 1.3.4 \d…

flask数据库操作

本文将详细介绍在Flask Web应用中如何设计数据库模型,并使用Flask-SQLAlchemy等扩展进行数据库操作的最佳实践。内容涵盖数据模型设计,ORM使用,关系映射,查询方法,事务处理等方面。通过本文,您可以掌握Flask数据库应用的基本知识。 Flask作为一个流行的Python Web框架,提供了高…

【Linux基础】WSL安装Ubuntu

说明 本文使用的Windows环境是Windows 11 专业版。 WSL现在有二代WSL2,后续都通过WSL2来安装Linux,使用的是Ubuntu发行版,版本是20.04。 安装过程使用了PowerShell,且是管理员权限打开的。 参考适用于 Linux 的 Windows 子系统…

DFS()

目录 DFS之连通性模型 迷宫 红与黑 DFS之搜索顺序 马走日 单词接龙 分成互质组 DFS之剪枝与优化 小猫爬山 数独 位运算 167. 木棒 生日蛋糕 迭代加深 加成序列 双向DFS 送礼物 IDA* 排书 回转游戏 DFS之连通性模型 dfs 与 bfs都能判断连通性 而且bfs可以…

#typescript 使用file-saver模块#

场景:前端使用file-saver模块做导出文档的时候,出现两个错误 1:npm run build 提示找不到模块,如图 解决方法: 先卸载,不管是否安装都先要卸载 ,然后安装: npm uninstall file-saver npm…

电子词典

项目要求: 1.登录注册功能,不能重复登录,重复注册。用户信息也存储在数据库中。 2.单词查询功能 3.历史记录功能,存储单词,意思,以及查询时间,存储在数据库 4.基于TCP,支持多客户…

【iOS】KVOKVC原理

1 KVO 键值监听 1.1 KVO简介 KVO的全称是Key-Value Observing,俗称"键值监听",可以用于监听摸个对象属性值得改变。 KVO一般通过以下三个步骤使用: // 1. 添加监听 [self.student1 addObserver:self forKeyPath:"age"…

【C++继承】

目录 一、继承的概念及定义1.1继承的概念1.2继承的定义1.2.1定义格式1.2.2继承方式与访问限定符的组合 二、基类和派生类对象赋值转换三、继承中的作用域四、派生类的默认成员函数五、继承与友元六、继承与静态成员七、复杂的菱形继承及菱形虚拟继承八、虚拟继承的原理 一、继承…

【C++进阶之路】多态篇

文章目录 前言一、概念1.分类2.实现条件①重写虚函数1.1总结三重1.2 final与override ②父类的指针或者引用2.1普通调用VS多态调用 3.抽象类3.1. 纯虚函数3.2. 接口继承和实现继承 二、原理及使用1.虚函数表 —— 虚表2.默认成员函数2.1构造函数2.2析构函数 3. 多继承3.1普通的…

用Ubuntu交叉编译Linux内核源码并部署到树莓派4B上

参考文章 1. 配置交叉编译环境 之前在ubuntu上配置过了,直接跳过 2.获取Linux内核源码 Linux内核源码链接 到链接里面选择自己合适版本的内核源码下载下来,然后传到ubuntu中进行解压 3.Linux内核源码的配置 参考文章 厂家配linux内核源码&#xff…

深入理解Gradle构建系统的工作原理

🌷🍁 博主猫头虎 带您 Go to New World.✨🍁 🦄 博客首页——猫头虎的博客🎐 🐳《面试题大全专栏》 文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺 &a…

使用贝叶斯滤波器通过运动模型和嘈杂的墙壁传感器定位机器人研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

【C++】多态的实现及其底层原理

个人主页:🍝在肯德基吃麻辣烫 我的gitee:gitee仓库 分享一句喜欢的话:热烈的火焰,冰封在最沉默的火山深处。 文章目录 前言一、什么是多态?二、多态的构成条件2.1什么是虚函数?2.2虚函数的重写2…

ICASSP 2023 | Cough Detection Using Millimeter-Wave FMCW Radar

原文链接:https://mp.weixin.qq.com/s?__bizMzg4MjgxMjgyMg&mid2247486540&idx1&sn6ebd9f58e9f08a369904f9c48e12d136&chksmcf51beb5f82637a3c65cf6fa53e8aa136021e35f63a58fdd7154fc486a285ecde8b8521fa499#rd ICASSP 2023 | Cough Detection Usi…

Qt中postevent造成内存泄漏问题的通用解决方案

在Qt中由QCoreApplication统一管理Qt事件的收发和销毁,其中sendEvent为阻塞式发送,用于单线程的事件发送;postevent为非阻塞式发送,构造事件的线程和接受事件的线程可以为两个线程。 最近在做一个个人项目ShaderLab 需要绘制OpenGL实时渲染的图像,由于OpenGL渲染基本都放…

论文笔记——Influence Maximization in Undirected Networks

Influence Maximization in Undirected Networks ContributionMotivationPreliminariesNotations Main resultsReduction to Balanced Optimal InstancesProving Theorem 3.1 for Balanced Optimal Instances Contribution 好久没发paper笔记了,这篇比较偏理论&…

python+django+mysql项目实践一(环境准备)

python项目实践 环境说明: Pycharm 开发环境 Django 前端 MySQL 数据库 Navicat 数据库管理 创建Pycharm项目 安装Django 在pycharm文件—设置进行安装 新建Django项目 注意项目创建目录 项目默认目录文件说明: __init__.py asgi.py 【异步接受网络…
最新文章