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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 10:20:58  来源:igfitidea点击:

Issue overriding application properties in Spring-boot (profile-specific) application launched with PropertiesLauncher

javapropertiesspring-bootoverriding

提问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 PropertiesLauncherrather 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.propertiescontains:

让我们说,为了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}.propertiesfile 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.propertiesfile ispicked up, the override of foo.baris ignored - I still see the value, bazfrom application-dev.propertiesrather than the value, overridden-valuefrom /local/appname/dev/overrides/application.properties.

我看到的问题是,虽然在文件中声明foo.password的属性选中,但忽略了 的覆盖- 我仍然看到值,来自而不是值,来自。application-dev.propertiesfoo.barbazapplication-dev.propertiesoverridden-value/local/appname/dev/overrides/application.properties

With the --debugoption enabled, I can see the ConfigFileApplicationListenerlogging 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.locationproperty, 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 解析属性的顺序,优先级降序排列:

  1. Command line arguments.
  2. Java System properties (System.getProperties()).
  3. OS environment variables.
  4. JNDI attributes from java:comp/env
  5. A RandomValuePropertySourcethat only has properties in random.*.
  6. Application properties outsideof your packaged jar (application.propertiesincluding YAML and profile variants).
  7. Application properties packaged insideyour jar (application.propertiesincluding YAML and profile variants).
  8. @PropertySourceannotations on your @Configurationclasses.
  9. Default properties (specified using SpringApplication.setDefaultProperties).
  1. 命令行参数。
  2. Java 系统属性 ( System.getProperties())。
  3. 操作系统环境变量。
  4. JNDI 属性来自 java:comp/env
  5. RandomValuePropertySource,只有在性random.*
  6. 打包 jar之外的应用程序属性(application.properties包括 YAML 和配置文件变体)。
  7. 打包jar 中的应用程序属性(application.properties包括 YAML 和配置文件变体)。
  8. @PropertySource你的@Configuration类的注释。
  9. 默认属性(使用 指定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.propertieswould 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.homeproperty, 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.homeinstead of spring.config.location, but to no avail.

所以我尝试使用loader.home而不是spring.config.location,但无济于事。

(Update: I also tried using loader.config.locationand 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/overridesto application-dev.propertiesthen the property values from that file dooverride the ones in classpath:application-dev.properties.

如果我将属性文件重命名为/local/appname/dev/overridesapplication-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.locationand got that wrong so it wasn't looking for the override file in the right place.

我确信我昨天已经尝试过这种组合,但我认为必须停止它工作的原因是当我在玩弄指定spring.config.location并出错时,所以它没有在正确的位置寻找覆盖文件。