Java 在使用PropertiesLauncher启动的Spring引导(特定于配置文件)应用程序中,出现覆盖应用程序属性的问题

Java 在使用PropertiesLauncher启动的Spring引导(特定于配置文件)应用程序中,出现覆盖应用程序属性的问题,java,properties,spring-boot,overriding,Java,Properties,Spring Boot,Overriding,我很难用文件系统上覆盖文件中声明的另一个值覆盖类路径上特定于概要文件的应用程序属性文件中声明的属性 我有一个自动配置的Spring引导应用程序(即使用@EnableAutoconfiguration),它有多个配置文件,我使用PropertiesLauncher而不是JarLauncher启动它(原因与部署限制有关——我需要将分解目录而不是归档文件部署到一个只读文件系统中。) 在我的应用程序的根目录中,我有一些特定于配置文件的应用程序属性,例如: application-dev.properti

我很难用文件系统上覆盖文件中声明的另一个值覆盖类路径上特定于概要文件的应用程序属性文件中声明的属性

我有一个自动配置的Spring引导应用程序(即使用
@EnableAutoconfiguration
),它有多个配置文件,我使用
PropertiesLauncher
而不是
JarLauncher
启动它(原因与部署限制有关——我需要将分解目录而不是归档文件部署到一个只读文件系统中。)

在我的应用程序的根目录中,我有一些特定于配置文件的应用程序属性,例如:

application-dev.properties
application-qa.properties
application-prd.properties
假设,
application-dev.properties
包含以下内容:

foo.bar=baz
foo.baz=other
对于任何环境,都可能需要重写现有属性,同时提供缺少的属性(例如,生产密码),我看到的问题是重写类路径上的
应用程序-${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
的覆盖被忽略-我仍然看到
application-dev.properties
中的值
baz
,而不是value,
重写值
来自
/local/appname/dev/overrides/application.properties

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

我可能会得出一个天真的结论,因为覆盖文件是首先列出的,所以它首先被加载,然后被类路径中的“默认”配置文件特定文件覆盖,这将在后面列出。但是,我确实理解,日志中列出的顺序不一定与行为相关。我已经尝试了varying在
spring.config.location
属性上声明的路径顺序,因此
classpath:
列在
文件:…
之前,但这没有帮助,而且我也不相信它会有帮助,因为spring引导文档清楚地说明,即使您提供了
spring.config.location
的值

Spring boot文档非常具体地描述了Spring boot可执行JAR的属性解析顺序,按优先级降序排列:

  • 命令行参数
  • Java系统属性(
    System.getProperties()
  • 操作系统环境变量
  • 来自
    java:comp/env的JNDI属性
  • 仅在
    random.*
    中具有属性的
    RandomValuePropertySource
  • 应用程序属性位于打包jar的外部(
    Application.properties
    包括YAML和概要文件变体)
  • 应用程序属性打包在jar中(
    Application.properties
    包括YAML和配置文件变体)
  • @PropertySource
    您的
    @配置
    类上的注释
  • 默认属性(使用
    SpringApplication.setDefaultProperties
    指定)
  • 注意第6行和第7行-属性外部在属性内部

    据我所知,没有说明的可能是我的困惑/问题的根源,是当您使用的不是JAR而是分解目录(因此
    PropertiesLauncher
    )时发生的情况

    如果分解目录的行为与JAR中声明的一致,我希望在
    /local/appname/dev/overrides/application.properties
    中声明的属性值会覆盖在
    classpath:application-dev.properties
    中声明的任何相同名称,但情况似乎并非如此

    Spring boot文档(关于
    PropertiesLauncher
    的附录C.4)中还提到了
    loader.home
    属性,它被描述为“…[附加属性文件的]位置,例如
    /opt/app
    (默认为
    ${user.dir}
    )”

    因此,我尝试使用
    loader.home
    而不是
    spring.config.location
    ,但没有效果

    (更新:我还尝试使用了
    loader.config.location
    ,我有两个注意事项:它似乎想要一个文件而不是一个目录(因此它的行为与
    spring.config.location
    类似),当我提供了一个文件路径而不是父目录时,它仍然没有帮助。)


    有人能看出我做错了什么,或者我做出了什么不正确的假设吗?

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

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

    我确信我已经试过了