【问题标题】:How to override SpringBoot config external file to classpath file?如何将 SpringBoot 配置外部文件覆盖到类路径文件?
【发布时间】:2021-11-02 23:09:11
【问题描述】:

当我通过命令行运行 jar 时,我想将 SpringBoot 外部的一些配置覆盖到类路径文件中。

类路径 -> application-config.yaml(不是 application.yaml)

server:
  port: 8080
  servlet:
    contextPath: /myapp
test-message: this config no need to export as external config.

外部 -> D:/test/application-config-override.yaml

server:
  port: 9090

命令

java -Dspring.config.location=classpath:application-config.yaml,file:///D:/test/application-config-override.yaml -jar myapp.jar

当我运行上面的命令时,应用程序正在运行 8080,contextPath 是“myapp”。我的预期是http://localhost:9090/myapp

但是,如果我将application-config.yaml 的所有相同的配置结构 放入application-config-override.yaml,如下所示

应用程序配置覆盖.yaml

server:
  port: 9090
  servlet:
    contextPath: /yourapp
test-message: this config no need to export as external

应用程序正在运行 9090,contextPath 是“yourapp”。

如何将 SpringBoot 外部的一些配置覆盖到类路径文件中?我正在使用 2.5.4。

我不想将一些不必要的配置导出到外部。我想按顺序调整和覆盖。

【问题讨论】:

  • yml文件名可以改吗?
  • @ray 可以更改。但。对于所有项目+所有 CICD Pipeline 来说,这将是更多的工作量。我们有一百多个微服务。它在 2.1.x 版本上运行良好
  • + 2.4.0 正在运行
  • 你试过我的答案了吗?

标签: java spring spring-boot spring-boot-configuration


【解决方案1】:

在 Windows 中,

java -jar demo.jar --spring.config.additional-location=file:///C:/Data/demo/application-config-override.yaml --spring.config.name=application-config,application-config-override

在linux中,

java -jar demo.jar --spring.config.additional-location=file:/home/user/config/application-config-override.yaml --spring.config.location=classpath:application-config.yaml

上述命令将解决您的需求。在 Spring 版本 2.5.4 上测试

【讨论】:

    【解决方案2】:

    尝试像这样同时提供spring.config.additional-locationspring.config.name

    -Dspring.config.additional-location=D:///test/ -Dspring.config.name=application-config,application-config-override
    

    【讨论】:

      【解决方案3】:

      既然您使用的是 SpringBoot,为什么不使用 SpringBoot 命名约定?如果您将文件命名为application.yaml,那么您将不必运行指定配置文件位置的 jar,因为 SpringBoot 会自动加载它们(如果它们位于默认位置)。

      将内部和外部文件都命名为 application.yaml,而不是 application-config.yamlapplication-config-override.yaml

      接下来,如果您将 yaml 文件放在 jar 之外,SpringBoot 会自动读取它并执行您想要实现的操作。

      这是我运行的测试:

      内部application.yaml 文件:

      value1: "internal" 
      value2: "internal"
      

      然后在应用程序中:

      @SpringBootApplication
      public class DemoApplication implements CommandLineRunner {
      
      @Value("${value1}")
      String val1;
      
      @Value("${value2}")
      String val2;
      
      
      public static void main(String[] args) {
          SpringApplication.run(DemoApplication.class, args);
      }
      
      @Override
      public void run(String... args) throws Exception {
          System.out.println("Value1: " + val1 + "\n" + "Value2: " + val2);
      }
      
      }
      

      然后当我在没有外部配置的情况下运行它时:

      java -jar demo-0.0.1-SNAPSHOT.jar

      INFO 6604 --- [主] com.example.demo.DemoApplication
      :在 1.611 秒内启动 DemoApplication(JVM 运行 2.118) 值1:内部值2:内部

      然后我将一个外部的 application.yaml 放在与 jar 相同的目录中:

      demo-0.0.1-SNAPSHOT.jar 
      application.yaml
      

      具有价值:

      value1: "external"
      

      那么输出是:

      java -jar demo-0.0.1-SNAPSHOT.jar

      2021-09-05 11:22:31.211 信息 23540 --- [主要] com.example.demo.DemoApplication : 启动 DemoApplication 1.552 秒(JVM 运行 2.101) 值1:外部值2:内部

      所以你可以看到外部value1 覆盖了内部value1

      这些配置文件按特定顺序和优先级加载。 来自SpringBoot Docs

      配置数据文件按以下顺序考虑:

      • 应用程序属性打包在您的 jar 中
      • 打包在 jar 中的特定于配置文件的应用程序属性
      • 打包 jar 之外的应用程序属性
      • 打包 jar 之外的特定于配置文件的应用程序属性

      【讨论】:

      • 感谢您的回答。它在 2.1.x 版本中工作。很难改变所有项目。我们有一百多个微服务。
      猜你喜欢
      • 2020-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-09
      • 2014-08-17
      • 2016-04-03
      相关资源
      最近更新 更多