java 使用 PropertiesLauncher 启动的 Spring-boot(特定于配置文件)应用程序中的问题覆盖应用程序属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26662381/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Issue overriding application properties in Spring-boot (profile-specific) application launched with PropertiesLauncher
提问by Damian
I'm having difficulty trying to override a property declared in a profile-specific application properties file on the classpath with another value declared in an overrides file on the file system.
我在尝试使用文件系统上的覆盖文件中声明的另一个值覆盖类路径上特定于配置文件的应用程序属性文件中声明的属性时遇到了困难。
I have an auto-configured Spring-boot application (that is, using @EnableAutoconfiguration
) that has multiple profiles, which I launch using PropertiesLauncher
rather than JarLauncher
(the reason having to do with deployment constraints - I need to deploy an exploded directory rather than an archive into a read-onlyfilesystem.)
我有一个自动配置的 Spring-boot 应用程序(即 using @EnableAutoconfiguration
),它具有多个配置文件,我使用PropertiesLauncher
而不是启动它JarLauncher
(原因与部署约束有关 - 我需要将展开的目录而不是存档部署到只读文件系统。)
Within the root of my application, I have some profile-specific application properties, for example:
在我的应用程序的根目录中,我有一些特定于配置文件的应用程序属性,例如:
application-dev.properties
application-qa.properties
application-prd.properties
And let's say, for the sake of argument that application-dev.properties
contains:
让我们说,为了application-dev.properties
包含以下内容的论证:
foo.bar=baz
foo.baz=other
For any environment, it may be necessary to override an existingproperty, as well as supply an absentone (like a production password, for example), and the issue I'm seeing is with overriding properties already declared in an application-${profile}.properties
file on the classpath. (Supplying properties not present in the classpath file works fine, this is notthe issue.)
对于任何环境,可能需要覆盖现有属性,并提供不存在的属性(例如,生产密码),我看到的问题是覆盖已在application-${profile}.properties
类路径上的文件中声明的属性. (提供类路径文件中不存在的属性工作正常,这不是问题。)
Say I have an overrides properties file in a file system location such as:
假设我在文件系统位置有一个覆盖属性文件,例如:
/local/appname/dev/overrides/application.properties
and I want to override the property, foo.bar
, as well as declare a new property, foo.password
.
并且我想覆盖属性 ,foo.bar
并声明一个新属性foo.password
。
Therefore the contents of the overrides file are:
因此覆盖文件的内容是:
foo.bar=overridden-value
foo.password=something
When I launch the application, I use a command line something like this:
当我启动应用程序时,我使用这样的命令行:
java -Dspring.config.location=file:/local/appname/dev/overrides/
-Dspring.profiles.active=dev
org.springframework.boot.loader.PropertiesLauncher
--debug &
The issue I am seeing is that although foo.password
, the property notdeclared in the application-dev.properties
file ispicked up, the override of foo.bar
is ignored - I still see the value, baz
from application-dev.properties
rather than the value, overridden-value
from /local/appname/dev/overrides/application.properties
.
我看到的问题是,虽然未在文件中声明foo.password
的属性被选中,但忽略了 的覆盖- 我仍然看到值,来自而不是值,来自。application-dev.properties
foo.bar
baz
application-dev.properties
overridden-value
/local/appname/dev/overrides/application.properties
With the --debug
option enabled, I can see the ConfigFileApplicationListener
logging that it has loaded both the overrides file (from the filesystem) and the profile-specific file (from the classpath), in that order.
--debug
启用该选项后,我可以看到ConfigFileApplicationListener
它已按顺序加载了覆盖文件(来自文件系统)和特定于配置文件的文件(来自类路径)的日志记录。
I'm tempted into the perhaps na?ve conclusion that because the overrides file is listed first, it is being loaded first then overridden by the 'default' profile-specific file from the classpath, which is listed later. I do appreciate however, that order of listing in the log doesn't necessarily correlate with behaviour. And I have tried varying the order of paths declared on the spring.config.location
property, so that classpath:
is listed before file:...
but this hasn't helped and I't not convinced it would anyway, given that the Spring-boot documentation clearly states that the default properties locations are always searched even if you supply a value for spring.config.location
.
我很想得出一个可能天真的结论,因为覆盖文件首先被列出,它首先被加载,然后被类路径中的“默认”特定于配置文件的文件覆盖,该文件在后面列出。然而,我确实很感激,日志中的列表顺序不一定与行为相关。我已经尝试改变在spring.config.location
属性上声明的路径的顺序,所以classpath:
前面file:...
已经列出了,但这并没有帮助,我也不相信它会起作用,因为 Spring-boot 文档明确指出默认属性位置是即使您为 提供了值,也始终会进行搜索spring.config.location
。
The Spring-boot documentation is very specific about the order that properties are resolved for a Spring-boot executable JAR, in descendingorder of precedence:
Spring-boot 文档非常具体地说明了为 Spring-boot 可执行 JAR 解析属性的顺序,按优先级降序排列:
- Command line arguments.
- Java System properties (
System.getProperties()
). - OS environment variables.
- JNDI attributes from
java:comp/env
- A
RandomValuePropertySource
that only has properties inrandom.*
. - Application properties outsideof your packaged jar (
application.properties
including YAML and profile variants). - Application properties packaged insideyour jar (
application.properties
including YAML and profile variants). @PropertySource
annotations on your@Configuration
classes.- Default properties (specified using
SpringApplication.setDefaultProperties
).
- 命令行参数。
- Java 系统属性 (
System.getProperties()
)。 - 操作系统环境变量。
- JNDI 属性来自
java:comp/env
- 一
RandomValuePropertySource
,只有在性random.*
。 - 打包 jar之外的应用程序属性(
application.properties
包括 YAML 和配置文件变体)。 - 打包在jar 中的应用程序属性(
application.properties
包括 YAML 和配置文件变体)。 @PropertySource
你的@Configuration
类的注释。- 默认属性(使用 指定
SpringApplication.setDefaultProperties
)。
Take note of lines 6 and 7 - properties outsideover properties insideyour jar.
记下第 6 行和第 7 行 - jar内部属性之外的属性。
What's not stated, as far as I can see, and which may be the source of my confusion/issue, is what happens when you're notusing a JAR but an exploded directory (and therefore PropertiesLauncher
.)
就我所见,没有说明的可能是我的困惑/问题的根源,是当您不使用 JAR 而是使用爆炸目录(因此PropertiesLauncher
.)
If the behaviour of an exploded directory were consistent with what's stated for a JAR, I'd expect that the values of properties declared in /local/appname/dev/overrides/application.properties
would override any of the same name declared in classpath:application-dev.properties
, but this doesn't seem to be the case.
如果分解目录的行为与 JAR 声明的行为一致,我希望 中声明的属性值/local/appname/dev/overrides/application.properties
将覆盖 中声明的任何相同名称classpath:application-dev.properties
,但情况似乎并非如此。
Also noted from the Spring-boot documentation (appendix C.4 on PropertiesLauncher
) is mention of the loader.home
property, which is described as '... [the] Location of additional properties file, e.g./opt/app
(defaults to ${user.dir}
)'.
Spring-boot 文档(附录 C.4 上PropertiesLauncher
)还提到了该loader.home
属性,它被描述为“... [the] 附加属性文件的位置,例如/opt/app
(默认为${user.dir}
)”。
So I tried using loader.home
instead of spring.config.location
, but to no avail.
所以我尝试使用loader.home
而不是spring.config.location
,但无济于事。
(Update: I also tried using loader.config.location
and I have two notes: it seems to want a file rather than a directory (so its behaviour is notanalogous with spring.config.location
), and when I didsupply a file path rather than the parent directory, it still didn't help.)
(更新:我使用也试着loader.config.location
和我有两个注意事项:它似乎是想建立一个文件,而不是一个目录(所以它的行为是不相似的带spring.config.location
),当我做还是提供文件路径,而不是父目录,它没没有帮助。)
Can anyone spot what I'm doing wrong, or what incorrect assumption(s) I'm making?
任何人都可以发现我做错了什么,或者我做出了哪些不正确的假设?
采纳答案by Damian
Thanks, Dave, your suggestion was 100% correct.
谢谢,戴夫,你的建议是 100% 正确的。
If I rename the properties file in /local/appname/dev/overrides
to application-dev.properties
then the property values from that file dooverride the ones in classpath:application-dev.properties
.
如果我将属性文件重命名为/local/appname/dev/overrides
,application-dev.properties
那么该文件中的属性值会覆盖classpath:application-dev.properties
.
I was sure I hadtried this combination yesterday, but I think what must have stopped it working was when I was playing around with specifying the spring.config.location
and got that wrong so it wasn't looking for the override file in the right place.
我确信我昨天已经尝试过这种组合,但我认为必须停止它工作的原因是当我在玩弄指定spring.config.location
并出错时,所以它没有在正确的位置寻找覆盖文件。