Spring Boot 配置文件(yml、properties | bootstrap、application)加载顺序
目录
前言
省流
代码验证
application
配置文件清单
示例代码
输出结果
bootstrap
配置文件清单
示例代码
输出结果
注意
前言
Spring 使用”约定大于配置“思想,简化了开发过程,提高了开发效率。不过只是简化了配置项,并不是完全不需要配置文件了,所以在实际开发中也需要根据实际情况,进行一些额外的配置来满足特定的需求。
在实际项目中,可能会看到各种各样的配置文件:
两种格式:
- yml
- properties
两种名字:
- application(默认扫描的配置文件名字)
- bootstrap(一般在微服务项目中才有)
不同环境:
- application-dev.yml / application-dev.properties
- application-prod.yml / application-prod.properties
要想知道写在配置文件里的配置项是否生效,就需要了解 Spring 框架是否会加载该配置文件,以及配置文件的加载顺序
省流
yml 文件优先加载于 properties 文件,后加载的配置项会覆盖先加载的配置项,所以如果 yml 和 peoperties 文件有相同的配置项,那么最终的值会是 properties 配置文件的值。
在单机版项目中:
配置文件加载顺序:application.yml > application.properties
在微服务项目中:
配置文件加载顺序:boostrap.yml > bootstrap.properties > application.yml > application.properties
不同环境的配置文件是否加载,则需要看 spring.profiles.active 的配置,如果 spring.profiles.active=dev,那么就会加载 application-dev.yml / application-dev.properties 配置文件。
代码验证
application
以下配置文件都在 resource 文件夹下
配置文件清单
application.yml
spring: profiles: active: dev application: yml: field: application.yml field: application.yml
application.properties
spring.profiles.active=dev application.prop.field=application.properties application.field=application.properties
application-dev.yml
application: dev: yml: field: application-dev.yml
application-dev.properties
application.dev.prop.field=application-dev.properties
application-prod.yml
application: prod: yml: field: application-prod.yml
applicaiton-prod.properties
application.prod.prop.field=application-prod.properties
示例代码
@SpringBootApplication
public class ActionApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(ActionApplication.class, args);
}
@Value("${application.prop.field:}")
String applicationProp;
@Value("${application.yml.field:}")
String applicationYml;
@Value("${application.field:}")
String application;
@Value("${application.dev.prop.field:}")
String applicationDevProp;
@Value("${application.dev.yml.field:}")
String applicationDevYml;
@Value("${application.prod.prop.field:}")
String applicationProdProp;
@Value("${application.prod.yml.field:}")
String applicationProdYml;
@Override
public void run(String... args) throws Exception {
System.out.println("applicationProp @value: " + applicationProp);
System.out.println("applicationYml @value: " + applicationYml);
System.out.println("application @value: " + application);
System.out.println("applicationDevProp @value: " + applicationDevProp);
System.out.println("applicationDevYml @value: " + applicationDevYml);
System.out.println("applicationProdProp @value: " + applicationProdProp);
System.out.println("applicationProdYml @value: " + applicationProdYml);
}
}
输出结果
可以看到控制台输出结果,证明 Spring 同时加载了 yml 文件 和 properties 文件。
因为 yml 文件优先加载,所以当 yml 和 properties 文件中存在相同的配置项,就会被后加载的 properties 文件覆盖掉。
以本文中的为例,application 最终得到的值是 application.properties,这个值是从 application.properties 文件中取的。
由于配置 spring.profiles.active 值为 dev,所以可以看到 applicationProdProp 和 applicationProdYml 拿到的值都为空字符串。
bootstrap
以下配置文件都在 resource 文件夹下
一般只有在微服务项目中才会有bootstrap配置文件
需要额外引入依赖
Spring Boot 版本小于 2.4.0 时需引入
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
</dependency>
Spring Boot 版本大于 2.4.0 时需引入
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
配置文件清单
boostrap.yml
bootstrap: yml: field: bootstrap.yml field1: bootstrap.yml field2: bootstrap.yml field3: bootstrap.yml field4: bootstrap.yml
boostrap.properties
bootstrap.prop.field=bootstrap.properties bootstrap.field2=bootstrap.properties bootstrap.field3=bootstrap.properties bootstrap.field4=bootstrap.properties
application.yml
application: yml: field: application.yml bootstrap: field3: application.yml field4: application.yml
application.properties
application.prop.field=application.properties bootstrap.field4=application.properties
示例代码
@SpringBootApplication
public class ActionApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(ActionApplication.class, args);
}
@Value("${bootstrap.prop.field:}")
String bootstrapProp;
@Value("${bootstrap.yml.field:}")
String bootstrapYml;
@Value("${bootstrap.field1:}")
String bootstrap1;
@Value("${bootstrap.field2:}")
String bootstrap2;
@Value("${bootstrap.field3:}")
String bootstrap3;
@Value("${bootstrap.field4:}")
String bootstrap4;
@Value("${application.prop.field:}")
String applicationProp;
@Value("${application.yml.field:}")
String applicationYml;
@Override
public void run(String... args) throws Exception {
System.out.println("bootstrapProp @value: " + bootstrapProp);
System.out.println("bootstrapYml @value: " + bootstrapYml);
System.out.println("applicationProp @value: " + applicationProp);
System.out.println("applicationYml @value: " + applicationYml);
System.out.println("bootstrap1 @value: " + bootstrap1);
System.out.println("bootstrap2 @value: " + bootstrap2);
System.out.println("bootstrap3 @value: " + bootstrap3);
System.out.println("bootstrap4 @value: " + bootstrap4);
}
}
输出结果
可以看到 boostrapProp bootstrapYml applicationProp applicaitonYml 都获取到了各自配置文件里的值,说明四个配置文件都被加载了。
而 bootstrap1 bootstrap2 bootstrap3 bootstrap4 的值依次是 bootstrap.yml bootstrap.properties applicaiton.yml applicaiton.properties,恰好证明了以上四个文件的加载顺序,后加载的配置文件覆盖了先加载的配置项。
注意
boostrap配置文件一般用于微服务项目中,一般是配置注册中心地址等基础配置项。看网上一些文章说boostrap中的配置项不会被覆盖,但是自己实操会发现配置项是可以被覆盖的。
其实是一些功能是基于bootstrap里的配置初始化的(比如配置服务器地址,服务注册地址之类的),所以配置项即使被覆盖了也无所谓了。