springcloud 配置文件优先级解析
spring cloud项目的很多功能功能建立在springboot基础之上,启动一个springcloud项目,首先会初始化一个bootstrap applicationContext, 然后会再初始化项目的main applicationContext, 而mainApplicationContext是bootstrapApplicationContext的子context,根据spring的知识,子context会继承父context的property sources and profiles,bootstrapContext的property sources有两个():
- “bootstrap”,如果context中有PropertySourceLocators的实例,并且这个实例包含非空的properties,则会有一个可选的CompositePropertySource存在,并且这个CompositePropertySource拥有最高的优先级,不能被本地配置覆盖。一般情况下,这个propertySource的来源是远程配置服务器。
-
“applicationConfig: [classpath:bootstrap.yml]”,这个配置文件中的属性,优先级最低,可以在里面设置默认值,它的属性值会被mainApplicationContext中的属性覆盖。
这两个context是共享同一个Environment的。
属性文件的相关配置
可以通过在系统属性中,设置spring.cloud.bootstrap.name(默认值,bootstrap) 或 spring.cloud.bootstrap.location (默认值为空)设置bootstrapApplicationContext的配置文件名称和位置。
如果想要覆盖bootstrap propertySource中的属性,可以通过下面两个属性设置
- spring.cloud.config.overrideNone=true , 配置本地属性可以覆盖bootstrap属性
- spring.cloud.config.overrideSystemProperties=false, 配置只有system properties, command line arguments, and environment variables可以覆盖远程属性
如果想在bootstrapApplicationContext初始化过程中,做点自己想做的事情,比如加载一些bean, 可以在项目的/META-INF/spring.factories文件中,添加一个键值对, key为org.springframework.cloud.bootstrap.BootstrapConfiguration,value为带@Configuration注解的配置类的类路径,
boogstrap 启动过程,默认的bootstrap property对应的外部配置来源是Spring Cloud Config Server, 如果想另外加载其它的属性值,可以配置一个自定义的PropertySourceLocator,并且在spring.factories中加上这个类。
@Configuration
public class CustomPropertySourceLocator implements PropertySourceLocator {
@Override
public PropertySource<?> locate(Environment environment) {
return new MapPropertySource("customProperty",
Collections.<String, Object>singletonMap("property.from.sample.custom.source", "worked as intended"));
}
}
当Environment中的属性变化时,application会观察到一个EnvironmentChangeEvent,这个事件包含了一个变化的key的list, 应用将用这个list做两件事情:
- 重新绑定context中的@ConfigurationProperties配置类
- 设置所有logging.level.* properties
属性值的解密,springcloud 有一个Environment
pre-processor,它会在mainApplicationContext获取Environment之前解密属性值,只要项目配置了和config server相同的 encrypt.*属性,Environment
pre-processor就会采用和config server一致的算法解密。另外,config server上加密的属性值前面要加上{cipher}。