小编典典

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

spring-boot

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

我有一个自动配置的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被忽略-我仍然看不到价值,bazapplication- dev.properties而不是值,overridden- value/local/appname/dev/overrides/application.properties

--debug启用该选项后,我可以看到ConfigFileApplicationListener它已 按顺序
加载了覆盖文件(来自文件系统)和特定于配置文件的文件(来自类路径)的日志记录。

我很想得出一个天真的结论,因为覆盖文件首先列出,因此它首先被加载,然后被来自类路径的“默认”配置文件专用文件覆盖,该文件随后列出。但是,我的确很高兴,日志中的列出顺序不一定与行为相关。而且我尝试过更改spring.config.location属性上声明的路径的顺序,因此上面classpath:列出了该顺序,file:...但这并没有帮助,并且我也不相信这样做,因为Spring-
boot文档明确指出了默认属性位置是即使您提供的值,也始终会搜索spring.config.location

Spring-boot文档非常详细地介绍了按优先级 从高到低的 顺序解析Spring-boot可执行JAR的属性的顺序:

  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)。

请注意第6行和第7行- jar 内部 属性 之外 的属性。 __

据我所知,未声明的内容(可能是我的困惑/问题的根源)是当您
使用JAR而是展开目录(因此使用)时发生的情况PropertiesLauncher

如果爆炸目录的行为与JAR声明的行为一致,则我希望在中声明的属性的值/local/appname/dev/overrides/application.properties将覆盖在中声明的任何同名名称classpath:application- dev.properties,但事实并非如此。

在Spring-boot文档(附录C.4 PropertiesLauncher)上还提到了该loader.home属性,该属性被描述为“ …
[。]其他属性文件的位置, 例如 /opt/app(默认为${user.dir})”。

因此,我尝试使用loader.home代替spring.config.location,但无济于事。

(更新:我使用也试着loader.config.location和我有两个注意事项:它似乎是想建立一个文件,而不是一个目录(所以它的行为是
相似的带spring.config.location),当我 还是提供文件路径,而不是父目录,它没没有帮助。)

谁能发现我做错了什么,或者我做错了什么假设?


阅读 2325

收藏
2020-05-30

共1个答案

小编典典

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

如果我将属性文件重命名为/local/appname/dev/overridesapplication- dev.properties则该文件中的属性值 覆盖中的属性值classpath:application- dev.properties

我确定我昨天 曾经
尝试过这种组合,但是我认为必须停止该组合的工作是在我尝试指定spring.config.location且出现错误时,因此它不在正确的位置查找替代文件。

2020-05-30