Loading

Spring Cloud Config 配置属性覆盖优先级

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

/**
 * Flag to indicate that {@link #isSystemPropertiesOverride()
 * 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 not override any
 * existing property sources (including local config files). Default false.
 */
private boolean overrideNone = false;

上面的代码截取至PropertySourceBootstrapProperties.java,可以看到有三个属性来控制覆盖的设置。

我们先不管Spring Cloud Config,就单单SpringBoot的变量覆盖根据官网的说法是以下的顺序(从上往下覆盖,也就是说最后的优先级是最低的)。

官网地址:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

Spring Boot uses a very particular PropertySource order that is designed to allow sensible overriding of values. Properties are considered in the following order:

Devtools global settings properties on your home directory (~/.spring-boot-devtools.properties when devtools is active).
@TestPropertySource annotations on your tests.
@SpringBootTest#properties annotation attribute on your tests.
Command line arguments.
Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or system property)
ServletConfig init parameters.
ServletContext init parameters.
JNDI attributes from java:comp/env.
Java System properties (System.getProperties()).
OS environment variables.
A RandomValuePropertySource that only has properties in random.*.
Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants)
Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants)
Application properties outside of your packaged jar (application.properties and YAML variants).
Application properties packaged inside your jar (application.properties and YAML variants).
@PropertySource annotations on your @Configuration classes.
Default properties (specified using SpringApplication.setDefaultProperties).

 

很清晰了吧,但如果走Spring Cloud Config这一套,如果你想本地提供一些参数覆盖远程配置文件的属性,在没有远程配置文件的允许下,是无法覆盖的。

所以他提供了那三个属性用来控制覆盖的选项。

另外,如果你不了解系统级(OS)环境变量和Java运行时参数的话,请看一下这个问答:https://stackoverflow.com/questions/13112038/difference-between-system-getenv-system-getproperty

好了,回到主题,我们可以看到overrideSystemProperties以及allowOverride这两个值是默认开启的。

其中overrideSystemProperties是覆盖Java运行时参数的也就是说,你通过下面的方式提供的属性,是会被远程的配置文件给覆盖的。

java -jar -Dserver.port=6666 myapp.jar

如果此时你的拓展属性文件中,包含了server.port这个值的话,那么你不会得到期望的6666,要使用的话,请在你的拓展属性文件中,注意,是在你的拓展属性文件中将这个值设置为false.

我们再来看一下allowOverride这个参数,上面说了,这个值是默认开启的,在注释中我们很清楚的了解到,如果允许被覆盖的话,这个值必须被设置为ture,但他默认就是ture,所以我们一般不用关心。

接下来看一下最重要的那个参数,即overrideNone,这个值依赖于上面所说的那个allowOverride等于true的情况下才有用,意思很清楚,注释说的很明白,即:如果为ture,外部拓展属性文件不会覆盖任何已经存在的值。已存在的值是指,非系统环境变量(如果你将overrideSystemProperties设置为false除外)。但如果 如此一来,我们通过命令行指定的参数 --xxxxx.xxxx=value,就不会被覆盖掉了。

有点绕,但是多看几遍之后还是能明白的。

一般来说,我们只需要将overrideNone设置为true,就能够通过命令行的方式,即--xxxx.xxx=value的方式设置属性值了,而且不会被覆盖掉。

 

最后千万千万注意的是,上面这三个属性存在于外部拓展时才会生效,如果你说为什么没有效果啊,请考虑为Spring Cloud Config当中存储的配置文件上加上上面所说的那些选项。

https://github.com/spring-cloud/spring-cloud-config/issues/359

这里作者说了:“ an app can't decide on its own that it can override configuration from the remote source”,即应用程序不能够自己决定是否能够覆盖,而是要在远程的配置文件中指明!

 

posted @ 2017-07-04 00:15  XingxueLiao  阅读(13932)  评论(2编辑  收藏  举报