Java 如何在Spring Boot的生产过程中覆盖application.properties?

Java 如何在Spring Boot的生产过程中覆盖application.properties?,java,spring,spring-boot,Java,Spring,Spring Boot,我使用spring boot和application.properties通过@Configuration@Profile(“dev”)在开发过程中选择数据库 在生产过程中,我希望在应用程序上下文之外创建一个文件,该文件应加载,然后激活一个不同的配置概要文件,其中包含d:/application.properties: spring.profiles.active=production 结果:当我启动应用程序时,配置仍然是dev,因此不知何故,没有考虑生产属性文件的附加位置。我遗漏了什么吗 s

我使用spring boot和
application.properties
通过
@Configuration@Profile(“dev”)
在开发过程中选择数据库

在生产过程中,我希望在应用程序上下文之外创建一个文件,该文件应加载,然后激活一个不同的配置概要文件,其中包含d:/application.properties:

spring.profiles.active=production
结果:当我启动应用程序时,配置仍然是
dev
,因此不知何故,没有考虑生产属性文件的附加位置。我遗漏了什么吗

spring boot 1.1.0.BUILD-SNAPSHOT


注意:这个问题不是关于tomcat的,我不确定你是否可以动态更改配置文件

为什么不将内部属性文件和spring.config.location属性设置为所需的外部位置,并且该位置(jar外部)的属性文件具有spring.profiles.active属性集

更好的是,有一个特定于dev profile(has spring.profiles.active=dev)的内部属性文件,并保持这样,当您希望在生产环境中部署时,为属性文件指定一个新位置,该文件包含spring.profiles.active=prod:

java -jar myjar.jar --spring.config.location=D:\wherever\application.properties
更新: 这是春天的一只虫子,看到了吗

jar之外的应用程序属性必须位于以下位置之一,然后一切都应该正常工作

21.2 Application property files
SpringApplication will load properties from application.properties files in the following    locations and add them to the Spring Environment:

A /config subdir of the current directory.
The current directory
A classpath /config package
The classpath root
因此,例如,当您不想指定cmd行参数并且在基本app.props中不使用spring.config.location时,这应该是可行的:

d:\yourExecutable.jar
d:\application.properties

or

d:\yourExecutable.jar
d:\config\application.properties

更新: 您可以将\@Configuration与\@PropertySource一起使用。
根据文档,您可以在任何地方指定资源。当加载哪个配置以确保您的产品成功时,您应该非常小心。

您也可以使用
@PropertySources

@PropertySources({
        @PropertySource(value = "classpath:application.properties"),
        @PropertySource(value = "file:/user/home/external.properties", ignoreResourceNotFound = true)
})
public class Application {
    public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);

    }


}

我知道你问过怎么做,但答案是你不应该这样做

相反,使用
应用程序.properties
应用程序默认.properties
应用程序-dev.properties
等,并通过args将配置文件切换到JVM:例如
-Dspring.profiles.active=dev

您还可以在测试时使用
@TestPropertySource

理想情况下,所有内容都应该在源代码管理中,这样就不会出现意外情况,例如,您如何知道服务器位置中有哪些属性,以及缺少哪些属性?如果开发人员引入新事物会发生什么

SpringBoot已经为您提供了足够的方法来正确完成此任务


我发现以下几点对我有效:

java -jar my-awesome-java-prog.jar --spring.config.location=file:/path-to-config-dir/
添加了
文件:

后期编辑

当然,此命令行在生产中从未运行过

我倒是有

  • 源代码管理中的[可能有几层]
    shell
    脚本,命令中可能更改的所有部分(jar名称、配置路径…)都有占位符
  • ansible
    部署脚本,它将部署
    shell
    脚本并用实际值替换占位符

弹簧配置优先级如下所示

  • ServletConfig初始参数
  • ServletContext初始化参数
  • JNDI属性
  • System.getProperties()

  • 因此,如果您希望这样做,您的配置将在命令行中被覆盖。但是建议避免重写,尽管您可以使用多个配置文件。

    从Spring Boot 2开始,您必须使用

    --spring.config.additional-location=production.properties
    

    使用Spring Boot 2.2.2.版本更新。

    这里有一个完整的例子

    假设在jar文件中,您有application.properties,它有以下两行:

    server.servlet.context-path=/test
    server.port=8081
    
    然后,在生产环境中,您希望覆盖server.port=8888,但不希望覆盖其他属性

    首先,创建另一个文件ex override.properties,并使该行联机:

    server.port=8888
    
    然后你可以像这样启动罐子

    java -jar spring-boot-1.0-SNAPSHOT.jar --spring.config.location=classpath:application.properties,/opt/somewhere/override.properties
    

    我会用另一种方法,为生产配置,为开发/测试覆盖。如果我没有弄错的话,
    spring.config.location
    只能从命令行设置,不能从属性文件中设置。spring.config.location可以从任何受支持的属性源配置,而不仅仅是命令行spring仍然支持ProertyPlacholder机制吗?如果是这样的话,您可能想研究一下。您发布的配置工作正常,Spring Boot没有任何问题。你必须有其他不起作用的东西,否则你可能会忽略项目中的某些东西。如何检查某个配置文件是否已加载,而不是另一个配置文件?是否有其他
    应用程序.properties
    文件位于项目的其他目录中?这就是我想要的方式:有一个内部
    应用程序.properties
    文件定义
    spring.config.location
    spring.profiles.active=dev
    和覆盖外部。但不起作用…不要在内部文件中定义spring.config.location,当您想部署到Production中时,只需将其指定为命令行参数是的,这将是一个选项,但我希望在启动时不必给出任何cmd args。特别是当spring boot声称支持此功能时……这可能只是我的设置中的一些怪癖,但是“-spring.config.location=…”对我来说不起作用。我必须使用“-Dspring.config.location=…”即“-D”not“-”。@StephenGelman别忘了将参数传递给SpringApplication。类似于
    publicstaticvoidmain(最终字符串[]args){SpringApplication.run(Application.class,args);}
    OK,这可能在可执行jar上工作,这很好!但是tomcat web应用程序呢?如何在部署的war应用程序外部加载类似于
    config
    dir的属性文件?因为,当我
    java -jar spring-boot-1.0-SNAPSHOT.jar --spring.config.location=classpath:application.properties,/opt/somewhere/override.properties