/** * 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”,即應用程序不能夠自己決定是否能夠覆蓋,而是要在遠程的配置文件中指明!