在使用PropertiesLauncher启动的Spring-boot(特定于配置文件)应用程序中发出覆盖应用程序属性的问题

时间:2014-10-30 20:11:00

标签: java properties spring-boot override

我很难尝试覆盖在类路径上特定于配置文件的应用程序属性文件中声明的属性,并在文件系统的覆盖文件中声明了另一个值。

我有一个自动配置的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解析属性的顺序:

  1. 命令行参数。
  2. Java系统属性(java:comp/env)。
  3. 操作系统环境变量。
  4. 来自RandomValuePropertySource
  5. 的JNDI属性
  6. 只有random.*中的属性的application.properties
  7. 打包jar的应用程序属性 application.properties包括YAML和配置文件变体)。
  8. 应用程序属性打包 您的jar(@PropertySource包括YAML和配置文件变体)。
  9. 您在@Configuration课程上的
  10. SpringApplication.setDefaultProperties注释。
  11. 默认属性(使用PropertiesLauncher指定)。
  12. 注意第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}}),当我 提供文件路径而不是父目录时,它仍然没有帮助。)

    任何人都可以发现我做错了什么,或者我正在做出哪些不正确的假设?

1 个答案:

答案 0 :(得分:9)

谢谢,戴夫,你的建议是100%正确的。

如果我将/local/appname/dev/overrides中的属性文件重命名为application-dev.properties,那么该文件中的属性值 执行 会覆盖{{1}中的属性值}}

我确信我已经昨天尝试了这个组合,但我认为必须停止它的工作是当我正在玩指定classpath:application-dev.properties并且弄错了所以它不是& #39; t在正确的位置寻找覆盖文件。