SpringBoot配置加载顺序
Spring Boot 不仅可以通过配置文件进行配置,还可以通过环境变量、命令行参数等多种形式进行配置。这些配置都可以让开发人员在不修改任何代码的前提下,直接将一套 Spring Boot 应用程序在不同的环境中运行
Spring Boot 配置优先级
以下是常用的 Spring Boot 配置形式及其加载顺序(优先级由高到低):
命令行参数
来自 java:comp/env 的 JNDI 属性
Java 系统属性(System.getProperties())
操作系统环境变量
RandomValuePropertySource 配置的 random.* 属性值
配置文件(YAML 文件、Properties 文件)
@Configuration 注解类上的 @PropertySource 指定的配置文件
通过 SpringApplication.setDefaultProperties 指定的默认属性
以上所有形式的配置都会被加载,当存在相同配置内容时,高优先级的配置会覆盖低优先级的配置;存在不同的配置内容时,高优先级和低优先级的配置内容取并集,共同生效,形成互补配置
配置文件加载顺序
通常情况下,Spring Boot 在启动时会将 resources 目录下的 application.properties 或 apllication.yml 作为其默认配置文件,我们可以在该配置文件中对项目进行配置,但这并不意味着 Spring Boot 项目中只能存在一个 application.properties 或 application.yml,Spring Boot 项目中可以存在多个 application.properties 或 apllication.yml
以上优先级中我们重点关注配置文件的加载顺序,这个是我们最常用的配置手段,Spring Boot 启动时,会自动加载 JAR 包内部及 JAR 包所在目录指定位置的配置文件(Properties 文件、YAML 文件),下图中展示了 Spring Boot 自动加载的配置文件的位置及其加载顺序,同一位置下,Properties 文件优先级高于 YAML 文件
上图中的节点说明如下:
/myBoot:表示 JAR 包所在目录,目录名称自定义;
/childDir:表示 JAR 包所在目录下 config 目录的子目录,目录名自定义;
JAR:表示 Spring Boot 项目打包生成的 JAR;
其余带有“/”标识的目录的目录名称均不能修改。
红色数字:表示该配置文件的优先级,数字越小优先级越高。
这些配置文件得优先级顺序,遵循以下规则:
先加载 JAR 包外的配置文件,再加载 JAR 包内的配置文件;
先加载 config 目录内的配置文件,再加载 config 目录外的配置文件;
先加载 config 子目录下的配置文件,再加载 config 目录下的配置文件;
先加载 appliction-{profile}.properties/yml,再加载 application.properties/yml;
先加载 .properties 文件,再加载 .yml 文件
我们做个实验
位于
classpath:/config/
下的配置文件内容为:
#类路径下的 config 目录下 #端口号为8084 #上下文路径为 /helloWorld server: port: 8084 servlet: context-path: /gcy
位于classpath:/
下的配置文件内容为:
#默认配置 server: port: 8080 person: name: tml age: 30 pets: -dog -cat -pig car: name: 蔚来es6 url: domain: www.baidu.com location: china
位于根目录下的配置文件为:
#项目根目录下 #上下文路径为 /tml server: servlet: context-path: /tml
启动后发现启动信息为
根据 Spring Boot 默认配置文件优先级进行分析:
该项目中存在多个默认配置文件,其中根目录下 /config 目录下的配置文件优先级最高,因此项目的上下文路径为 /tml;
类路径(classpath)下 config 目录下的配置文件优先级高于类路径下的配置文件,该项目的端口号为8084;
以上所有配置项形成互补,所以访问路径为http://localhost:8084/tml/hello。
但是有一点需要注意,如果当前激活指定了spring.profiles.active: @env@某个配置文件,那么按照上述配置加载顺序走激活指定的Profile配置文件,如果不指定激活Profile,那么是不会加载appliction-{profile}.properties/yml配置文件,按照上述配置顺序加载appliction.properties/yml配置文件
总结一下
之前一直看不懂profile是干嘛的,现在终于知道了,是为了切换环境时使用不同配置身份用的,这个可比C#方便多了,记得之前拉代码的时候老会遇到配置被别人改到测试了,现在有了Maven的环境切换,方便多了,本地随便改。即使我们知道SpringBoot有这么多的配置优先级,其实实际用的时候我们也都是简单用,配置好启动身份后,我们一般只在类路径(classpath)下添加各个环境配置文件然后加载使用,避免混乱,但是大概了解下加载逻辑也便于之后方便排查问题。