SpringCloud配置中心优先级

SpringCloud 配置中心优先级

01.02-SpringCloud 配置中心优先级

1. springboot 的配置优先级

命令行参数 > 操作系统环境变量 > 应用外的配置文件 > 应用内的配置文件

这里命令行参数设置的优先级是最高的,方便部署不同环境。

2. 加入 springcloud 配置中心后

加入 springcloud 的配置中心后,优先级并不是想象中的命令行最高优先级。

我实验后得到的优先级有:配置中心 > 命令行参数 > 本地 application.yml > 本地 bootstrap.yml

它的设计者认为,配置中心就是最高优先级的,不允许外部修改。

如果想要覆盖,可在远程配置中加下面配置

1
2
3
4
5
6
spring:  
cloud:
config:
allowOverride: true
overrideNone: true
overrideSystemProperties: false

上面的说法可以在如下链接中得到验证:https://cloud.spring.io/spring-cloud-commons/multi/multi__spring_cloud_context_application_context_services.html#overriding-bootstrap-properties

3. 源码解析

org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration#insertPropertySources

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
PropertySourceBootstrapProperties remoteProperties = new PropertySourceBootstrapProperties();
Binder.get(environment(incoming)).bind("spring.cloud.config",
Bindable.ofInstance(remoteProperties));
// 跟进3个参数的组合,决定远程参数加入environment的开头还是结尾
if (!remoteProperties.isAllowOverride() || (!remoteProperties.isOverrideNone()
&& remoteProperties.isOverrideSystemProperties())) {
for (PropertySource<?> p : reversedComposite) {
propertySources.addFirst(p);
}
return;
}
if (remoteProperties.isOverrideNone()) {
for (PropertySource<?> p : composite) {
propertySources.addLast(p);
}
return;
}
if (propertySources.contains(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME)) {
if (!remoteProperties.isOverrideSystemProperties()) {
for (PropertySource<?> p : reversedComposite) {
propertySources.addAfter(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, p);
}
}
else {
for (PropertySource<?> p : composite) {
propertySources.addBefore(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, p);
}
}
}
else {
for (PropertySource<?> p : composite) {
propertySources.addLast(p);
}
}

remoteProperties 默认值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@ConfigurationProperties("spring.cloud.config")
public class PropertySourceBootstrapProperties {

/**
* Flag to indicate that the external properties should override system properties.
* Default true.
*/
private boolean overrideSystemProperties = true;

/**
* Flag to indicate that {@link #isOverrideSystemProperties()
* systemPropertiesOverride} can be used. Set to false to prevent users from changing
* the default accidentally. Default true.
*/
private boolean allowOverride = true;

/**
* Flag to indicate that when {@link #setAllowOverride(boolean) allowOverride} is
* true, external properties should take lowest priority and should not override any
* existing property sources (including local config files). Default false.
*/
private boolean overrideNone = false;
}

org.springframework.core.env.PropertySourcesPropertyResolver#getProperty(java.lang.String, java.lang.Class, boolean)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
protected <T> T getProperty(String key, Class<T> targetValueType, boolean resolveNestedPlaceholders) {
if (this.propertySources != null) {
for (PropertySource<?> propertySource : this.propertySources) {
if (logger.isTraceEnabled()) {
logger.trace("Searching for key '" + key + "' in PropertySource '" +
propertySource.getName() + "'");
}
Object value = propertySource.getProperty(key);
if (value != null) {
if (resolveNestedPlaceholders && value instanceof String) {
value = resolveNestedPlaceholders((String) value);
}
logKeyFound(key, propertySource, value);
return convertValueIfNecessary(value, targetValueType);
}
}
}
if (logger.isTraceEnabled()) {
logger.trace("Could not find key '" + key + "' in any property source");
}
return null;
}

当应用程序获取参数值(@Value 注解、显示调用 environment.getProperty()时)一样,environment 的查询方式是按照先后顺序查找参数值。

从结果上看,nacos 配置的顺序在命令之前,故 nacos 的优先级更高。