【问题标题】:How to override application.properties during production in Spring-Boot?如何在 Spring-Boot 的生产过程中覆盖 application.properties?
【发布时间】:2014-06-27 02:52:39
【问题描述】:

我正在使用spring boot和application.properties@Configuration @Profile("dev")开发期间选择数据库。

spring.profiles.active=dev
spring.config.location=file:d:/application.properties

在生产期间,我想在应用程序上下文之外创建一个应该加载的文件,然后使用 d:/application.properties:激活不同的配置文件:

spring.profiles.active=production

结果:当我启动应用程序时,配置仍然是dev,所以不知何故没有考虑生产属性文件的附加位置。我错过了什么吗?

spring boot 1.1.0.BUILD-SNAPSHOT

注意:这个问题不是关于 tomcat

【问题讨论】:

  • 我会反过来做,为生产配置并为开发/测试覆盖。如果我没记错的话,spring.config.location 只能从命令行设置,不能从属性文件中设置。
  • spring.config.location 可以从任何受支持的属性源进行配置,而不仅仅是命令行
  • Spring 还支持 ProertyPlacholder 机制吗?如果是这样,您可能想调查一下。
  • 您发布的配置有效,Spring Boot没有问题。您必须有其他不起作用的东西,或者您可能忽略了项目中的某些内容。如何检查某个配置文件是否已加载,而不是另一个?
  • 您的项目的其他目录中是否还有其他application.properties 文件?

标签: java spring spring-boot


【解决方案1】:

从 Spring Boot 2 开始,您将不得不使用

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

【讨论】:

    【解决方案2】:

    使用 Spring Boot 2.2.2.Release 更新。

    这里有完整的例子,https://www.surasint.com/spring-boot-override-property-example/

    假设,在您的 jar 文件中,您的 application.properties 包含这两行:

    server.servlet.context-path=/test
    server.port=8081
    

    然后,在生产中,您想要覆盖 server.port=8888 但不想覆盖其他属性。

    首先,您创建另一个文件,例如 override.properties 并让这一行在线:

    server.port=8888
    

    然后就可以这样启动jar了

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

    【讨论】:

    • 这不再起作用了。您应该使用 --spring.config.additional-location 覆盖默认属性
    • 如果你想用 --spring.config.location=classpath:application.properties,/opt/somewhere/override.properties 覆盖你必须覆盖新文件中的所有属性默认文件
    • @homeOfTheWizard 你用的是哪个版本?
    • 我使用的是 2.2.6.Release
    • 非常感谢。它适用于 Spring Boot 2.3.4(属性或 yml 文件)
    【解决方案3】:

    我知道你问过如何做到这一点,但答案是你不应该这样做。

    相反,有一个application.propertiesapplication-default.properties application-dev.properties 等,并通过 args 将配置文件切换到 JVM:例如-Dspring.profiles.active=dev

    你也可以在测试时使用@TestPropertySource覆盖一些东西

    理想情况下,一切都应该在源代码管理中,这样就不会出现意外,例如您如何知道您的服务器位置中有哪些属性,哪些属性丢失了?如果开发人员引入新事物会怎样?

    Spring Boot 已经为您提供了足够的方法来做到这一点。

    https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

    【讨论】:

    • 虽然这个问题是我早期使用 spring-boot 提出的,但我现在同意配置文件只能在运行 jar/war 时通过命令行参数spring.profiles.active=production 激活。所以我会接受你的回答。
    • 如果配置文件设置为productionapplication.properties 会运行吗?
    • 是的,它会做应用程序和应用程序生产,如果属性相同,以后将作为覆盖工作
    • 虽然使用 spring 配置文件对配置值集进行分组可能是 Spring/Java 中的常见做法,但重要的是要指出,这不是现代服务和应用程序的最佳做法,尤其是那些旨在追随云计算的应用程序本地实践,例如 12factor.net/config 中描述的。
    • 他们说使用环境变量,这是一个笑话。在我的应用程序中,我有配置服务器,它有 yml 文件和 hashcorp vault。该应用程序位于 pcf 中。配置独立于代码签入到 git,这已经足够了。 yml 允许导入其他 ymls
    【解决方案4】:

    spring配置优先级如下。

    1. ServletConfig 初始化参数
    2. ServletContext 初始化参数
    3. JNDI 属性
    4. System.getProperties()

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

    【讨论】:

      【解决方案5】:

      我发现以下内容对我有用:

      java -jar my-awesome-java-prog.jar --spring.config.location=file:/path-to-config-dir/
      

      添加了 file:

      后期编辑

      当然,这个命令行从不在生产环境中运行。

      我有

      • [可能是几层]shell 源代码控制中的脚本,其中包含可能更改的所有命令部分的占位符(jar 名称、配置路径...)
      • ansible 部署脚本将部署 shell 脚本并将占位符替换为实际值。

      【讨论】:

      • 这可能是因为答案发布在之前版本的 SB
      【解决方案6】:

      你也可以使用@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);
      
          }
      
      
      }
      

      【讨论】:

      • 对我有两点意见:1. 第二个资源中的定义覆盖第一个资源中的定义。 2. 除非第一个资源被命名为application.properties(至少在 Spring 4.3.20 版中) 似乎 Spring 4 有一个阻止覆盖的错误。只需重命名 application.properties -> app.properties 就可以了。
      【解决方案7】:

      更新: 这是春天的一个错误,请参阅here

      您的 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 行 args 并且您不在基本 app.props 中使用 spring.config.location 时,这应该可以工作:

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

      spring external config doc

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

      【讨论】:

      • 好的,这可能适用于可执行的 jar,太棒了!但是 tomcat web 应用程序呢?如何在部署的战争应用程序之外加载类似于config 目录的属性文件?因为,当我重新部署应用程序时,所有创建的子文件夹都会丢失。
      • 使用 propertysource 只要你的 spring 版本足够好,它就应该可以看到更新
      • @dasAnderl '@PropertySource' 在部署战争时加载属性的问题是日志属性将被忽略并且日志系统将无法工作。检查这个替代solution
      【解决方案8】:

      我不确定您是否可以动态更改配置文件。

      为什么不将 spring.config.location 属性设置为您想要的外部位置的 internal 属性文件,以及该位置的属性文件(在jar) 是否设置了 spring.profiles.active 属性?

      更好的是,有一个内部属性文件,特定于开发配置文件(有 spring.profiles.active=dev)并保持原样,当您想在生产中部署时,为您的属性文件指定一个新位置,其中有 spring.profiles.active=prod:

      java -jar myjar.jar --spring.config.location=D:\wherever\application.properties
      

      【讨论】:

      • 这就是我想要的方式:有一个内部的application.properties 文件定义spring.config.locationspring.profiles.active=dev 并覆盖外部。但不起作用...
      • 不要在你的内部文件中定义 spring.config.location ,当你想部署到生产环境时将它指定为命令行参数
      • 是的,这是一个选项,但我想避免在启动时提供任何 cmd 参数。特别是弹簧靴声称支持这一点......
      • 这可能只是我的设置中的一些怪癖,但“--spring.config.location=...”对我不起作用。我必须使用“-Dspring.config.location=...” 那是“-D”而不是“--”。
      • @StephenGelman 不要忘记将参数传递给 SpringApplication。喜欢public static void main(final String[] args) { SpringApplication.run(Application.class, args);}
      猜你喜欢
      • 1970-01-01
      • 2015-05-18
      • 2019-08-20
      • 2017-01-24
      • 2020-03-04
      • 2020-06-22
      • 2015-06-22
      • 2020-05-03
      • 2018-04-12
      相关资源
      最近更新 更多