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”,即应用程序不能够自己决定是否能够覆盖,而是要在远程的配置文件中指明!