我很难尝试覆盖在类路径上特定于配置文件的应用程序属性文件中声明的属性,并在文件系统的覆盖文件中声明了另一个值。
我有一个自动配置的Spring-boot应用程序(即使用@EnableAutoconfiguration
),它有多个配置文件,我使用PropertiesLauncher
而不是JarLauncher
启动(原因是必须处理部署限制 - 我需要将展开的目录而不是存档部署到只读文件系统中。)
在我的应用程序的根目录中,我有一些特定于配置文件的应用程序属性,例如:
application-dev.properties
application-qa.properties
application-prd.properties
让我们说,为了论证application-dev.properties
包含:
foo.bar=baz
foo.baz=other
对于任何环境,可能需要覆盖现有属性,并提供缺席属性(例如生产密码),以及我看到的问题是在类路径的application-${profile}.properties
文件中已经声明了重写属性。 (提供类路径文件中不存在的属性工作正常,这是不问题。)
假设我在文件系统位置有一个覆盖属性文件,例如:
/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
application-dev.properties
文件 中声明的属性 不 拾取 ,忽略foo.bar
的覆盖 - 我仍然会看到来自baz
的值application-dev.properties
,而不是来自overridden-value
的值/local/appname/dev/overrides/application.properties
--debug
。
启用ConfigFileApplicationListener
选项后,我可以看到它已加载覆盖文件(来自文件系统)和特定于配置文件的文件(来自类路径)的spring.config.location
日志记录, 按此顺序 。
我很想得出这样一个天真的结论:因为首先列出了覆盖文件,所以首先加载它然后被类路径中的'default'特定于配置文件的文件覆盖,后面会列出。但我很欣赏,日志中的列表顺序不一定与行为相关。我尝试改变classpath:
属性上声明的路径顺序,以便在file:...
之前列出spring.config.location
,但这没有帮助,我不相信它会反正,鉴于Spring-boot文档明确指出即使您为System.getProperties()
提供值,也始终会搜索默认属性位置。
Spring-boot文档非常具体地说明了以降序优先顺序为Spring引导可执行JAR解析属性的顺序:
java:comp/env
)。RandomValuePropertySource
random.*
中的属性的application.properties
。application.properties
包括YAML和配置文件变体)。@PropertySource
包括YAML和配置文件变体)。@Configuration
课程上的SpringApplication.setDefaultProperties
注释。PropertiesLauncher
指定)。注意第6和第7行 - 属性 属性 你的jar。
据我所知,未说明的内容,以及可能是我的混淆/问题的根源,当您使用 时会发生什么JAR但是一个展开的目录(因此/local/appname/dev/overrides/application.properties
。)
如果展开目录的行为与JAR的内容一致,我希望classpath:application-dev.properties
中声明的属性值将覆盖PropertiesLauncher
中声明的任何相同名称,但事实似乎并非如此。
从Spring-boot文档(附录C.4 loader.home
)中还注意到/opt/app
属性,它被描述为'... [其他属性文件的位置] ,例如 ${user.dir}
(默认为loader.home
)'。
所以我尝试使用spring.config.location
代替loader.config.location
,但无济于事。
(更新:我也尝试使用spring.config.location
并且我有两个注意事项:它似乎想要一个文件而不是一个目录(所以它的行为是 不 类似于{{1}}),当我 提供文件路径而不是父目录时,它仍然没有帮助。)
任何人都可以发现我做错了什么,或者我正在做出哪些不正确的假设?
答案 0 :(得分:9)
谢谢,戴夫,你的建议是100%正确的。
如果我将/local/appname/dev/overrides
中的属性文件重命名为application-dev.properties
,那么该文件中的属性值 执行 会覆盖{{1}中的属性值}}
我确信我已经昨天尝试了这个组合,但我认为必须停止它的工作是当我正在玩指定classpath:application-dev.properties
并且弄错了所以它不是& #39; t在正确的位置寻找覆盖文件。