Spring Cloud 构建于 Spring Boot 之上,在 Spring Boot 中有两种上下文,一种是 bootstrap,另外一种是 application。
bootstrap.yml/bootstrap.properties 和 application.yml/application.yml 都可以用来配置参数。
bootstrap.yml/bootstrap.properties :用来程序引导时执行,应用于更加早期配置信息读取。可以理解成系统级别的一些参数配置,这些参数一般是不会变动的。
application.yml/application.yml :可以用来定义应用级别的, 应用程序特有配置信息,可以用来配置后续各个模块中需使用的公共参数等。
文件名.properties /文件名.yml文件名相同且同时存在时,先加载 .properties 文件,再加载 .yml 文件。
若application.yml/.properties 和 bootstrap.yml/.properties 在同一目录下:bootstrap先加载,application 后加载
bootstrap.yml/.properties 和 application.yml/.properties 共享同一个 Environment。Environment 它是任何 Spring 应用程序的外部属性的来源。bootstrap.yml/.properties 属性以高优先级添加,因此默认情况下它们不能被本地配置覆盖。而 application.yml/.properties 的配置项可以被覆盖。
可通过参数spring.cloud.bootstrap.enabled=true完全禁用bootstrap。
更多详细配置及说明请见官网:
https://docs.spring.io/spring-boot/docs/2.0.4.RELEASE/reference/htmlsingle/#boot-features-external-config
相信有不少细心小伙伴在新启动一个spring boot项目时候会发现这样一条信息no active profile set, falling back to default profiles: default。为什么会出现这样的提示呢,我们先来看看profile,profile是Spring对不同环境提供不同配置功能的支持,可以通过激活、 指定参数等方式快速切换环境profile。举个例子我们在开发,测试,生产用到的配置是不同的,那么通过profile就可以帮我们指定对应的环境用对应的配置,那么如何来指定呢?
格式:application-{profile}.properties/yml ,在resources目录下:
默认:application.properties
共用配置:application-common.properties
开发环境:application-dev.properties
生产环境:application-prod.properties
测试环境:application-test.properties
在application.properties 中配置:
spring.profiles.active=dev
或在application.yml 中配置:
spring: profiles: active: dev
进行多配置激活,如下:
spring.profiles.active=dev,common
HelloWorldApplication.java
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; import java.util.concurrent.TimeUnit; @SpringBootApplication public class HelloWorldApplication { public static void main(String[] args) throws InterruptedException { ConfigurableApplicationContext applicationContext = SpringApplication.run(HelloWorldApplication.class, args); while (true) { //当动态配置刷新时,会更新到 Enviroment中,因此这里每隔一秒中从Enviroment中获取配置 String name = applicationContext.getEnvironment().getProperty("name"); String age = applicationContext.getEnvironment().getProperty("age"); System.err.println("=========>>>>>>>>>>name :" + name + ",age :" + age); TimeUnit.SECONDS.sleep(1); } } }
application.properties
spring.profiles.active=dev,common name=default age=0
application-common.properties
name=common
application-dev.properties
name=dev age=18
运行结果
若项目同一目录同时存在以下四个文件:
bootstrap.properties bootstrap.yml application.properties application.yml
bootstrap的配置先于application的配置加载,同时.properties的加载又先于.yml的加载,即加载优先级:
bootstrap.properties -> bootstrap.yml -> application.properties -> application.yml
若项目同一目录同时存在以下四个文件:
bootstrap-dev.yml bootstrap.properties application-dev.yml application.properties
此时的加载优先级变为:
bootstrap-dev.yml -> bootstrap.properties -> application-dev.yml -> application.properties。
且同属性配置的覆盖问题和之前一样:
举例1:假如此时只有bootstrap-dev.yml 和bootstrap.properties且存在相同配置,则使用bootstrap-dev.yml中的配置,此时遵循高优先级覆盖低优先级。
举例2:假如此时有bootstrap-dev.yml 、bootstrap.properties及application.properties且存在相同配置,则使用application.properties中的配置,遵循application覆盖bootstrap原则,同样此时变成了低优先级覆盖高优先级。
注意:如bootstrap中配置spring.profiles.active: dev,并在application中配置spring.profiles.active: test,此时读取的bootstrap-{profile}.properties/yml和application-{profile}.properties/yml中参数{profile}为dev即application中配置未生效。
通常情况下,Spring Boot 在启动时会将 resources 目录下的 application.properties 或 apllication.yml 作为其默认配置文件,我们可以在该配置文件中对项目进行配置,但这并不意味着 Spring Boot 项目中只能存在一个 application.properties 或 application.yml,Spring Boot 项目中可以存在多个 application.properties 或 apllication.yml。
上图中的节点说明如下:
这些配置文件得优先级顺序,遵循以下规则:
以下是常用的 Spring Boot 配置形式及其加载顺序(优先级由高到低):
所有的配置都可以在命令行上进行指定:
java -jar {Jar文件名} --{参数1}={参数值1} --{参数2}={参数值2}
例如,可以通过指定 --spring.config.location来改变默认的配置文件位置,通过指定 --spring.profiles.active激活环境:
java -jar properties-0.0.1-SNAPSHOT.jar --spring.config.location=classpath:./ --spring.profiles.active=test
例如,可以通过指定 -Dspring.profiles.active激活环境:
java -jar properties-0.0.1-SNAPSHOT.jar -Dspring.profiles.active=test
操作系统环境变量
jar包外部的application-{profile}.properties或application-{profile}.yml(带spring.profile)配置文件。
jar包内部的application-{profile}.properties或application-{profile}.yml(带spring.profile)配置文件。
jar包外部的application.properties或application.yml(不带spring.profile)配置文件。
jar包内部的application.properties或application.yml(不带spring.profile)配置文件。
@Configuration 注解类上的 @PropertySource 指定的配置文件
通过 SpringApplication.setDefaultProperties 指定的默认属性
以上所有形式的配置都会被加载,当存在相同配置内容时,高优先级的配置会覆盖低优先级的配置;存在不同的配置内容时,高优先级和低优先级的配置内容取并集,共同生效,形成互补配置,大体顺序如下:program arguments > VM options > Enviroment variables > properties文件 > yml文件。