我在尝试使用文件系统上的覆盖文件中声明的另一个值来覆盖类路径上特定于配置文件的应用程序属性文件中声明的属性时遇到困难。
我有一个自动配置的 Spring-boot 应用程序(即,使用@EnableAutoconfiguration
)有多个配置文件,我使用它启动PropertiesLauncher
而不是JarLauncher
(原因与部署限制有关 - 我需要将分解的目录而不是存档部署到只读文件系统。)
在我的应用程序的根目录中,我有一些特定于配置文件的应用程序属性,例如:
application-dev.properties
application-qa.properties
application-prd.properties
为了论证起见,我们可以说application-dev.properties
包含:
foo.bar=baz
foo.baz=other
对于任何环境,可能需要覆盖existing财产,以及提供absent一个(例如,生产密码),我看到的问题是已经在application-${profile}.properties
类路径上的文件。 (提供类路径文件中不存在的属性可以正常工作,这是not问题。)
假设我在文件系统位置有一个覆盖属性文件,例如:
/local/appname/dev/overrides/application.properties
我想覆盖该属性,foo.bar
,以及声明一个新属性,foo.password
.
因此覆盖文件的内容是:
foo.bar=overridden-value
foo.password=something
当我启动应用程序时,我使用如下命令行:
java -Dspring.config.location=file:/local/appname/dev/overrides/
-Dspring.profiles.active=dev
org.springframework.boot.loader.PropertiesLauncher
--debug &
我看到的问题是虽然foo.password
, 财产not声明于application-dev.properties
file is拾取,覆盖foo.bar
被忽略 - 我仍然看到它的价值,baz
from application-dev.properties
而不是价值,overridden-value
from /local/appname/dev/overrides/application.properties
.
随着--debug
选项已启用,我可以看到ConfigFileApplicationListener
记录它已加载覆盖文件(来自文件系统)和配置文件特定文件(来自类路径),以该顺序.
我很想得出一个也许天真的结论,因为覆盖文件首先列出,所以它首先被加载,然后被类路径中的“默认”配置文件特定文件覆盖,该文件稍后列出。不过,我确实很欣赏,日志中的列出顺序不一定与行为相关。我尝试改变声明的路径的顺序spring.config.location
财产,使得classpath:
之前列出的file:...
但这并没有帮助,而且我也不相信它会起作用,因为 Spring-boot 文档明确指出,即使您提供了值,也始终会搜索默认属性位置spring.config.location
.
Spring-boot 文档对于 Spring-boot 可执行 JAR 的属性解析顺序非常具体,在下降优先顺序:
- 命令行参数。
- Java 系统属性(
System.getProperties()
).
- 操作系统环境变量。
- JNDI 属性来自
java:comp/env
- A
RandomValuePropertySource
只具有属性random.*
.
- 应用属性outside你打包的罐子(
application.properties
包括 YAML 和配置文件变体)。
- 打包的应用程序属性inside你的罐子(
application.properties
包括 YAML 和配置文件变体)。
-
@PropertySource
对你的注释@Configuration
类。
- 默认属性(使用指定
SpringApplication.setDefaultProperties
).
注意第 6 行和第 7 行 - 属性outside超过属性inside你的罐子。
据我所知,没有说明的是,这可能是我困惑/问题的根源,当你not使用 JAR 但使用分解的目录(因此PropertiesLauncher
.)
如果分解目录的行为与 JAR 的规定一致,我希望在中声明的属性值/local/appname/dev/overrides/application.properties
将覆盖任何相同名称中声明的classpath:application-dev.properties
,但事实似乎并非如此。
还从 Spring-boot 文档(附录 C.4)中注意到PropertiesLauncher
)是提到loader.home
属性,被描述为“...[附加属性文件的]位置”,e.g. /opt/app
(默认为${user.dir}
)'.
所以我尝试使用loader.home
代替spring.config.location
,但无济于事。
(更新:我也尝试使用loader.config.location
我有两个注释:它似乎想要一个文件而不是一个目录(所以它的行为是not类似于spring.config.location
),当我did提供文件路径而不是父目录,它仍然没有帮助。)
谁能发现我做错了什么,或者我做了什么错误的假设?