【问题标题】:Maven install command with environment variables file带有环境变量文件的 Maven 安装命令
【发布时间】:2020-08-02 20:13:07
【问题描述】:

有什么方法可以执行环境变量文件.env 以及mvn clean installmvn clean deploy 等maven 命令。我正在寻找类似解决方案的概念背后的主要思想:

mvn clean install -DenvFile=/path/<filename>.env

mvn clean deploy -DenvFile=/path/<filename>.env

mvn clean package -DenvFile=/path/<filename>.env

注意:不尝试生成特定于环境的构建。在开发环境中,我打算使用所有 从&lt;filename&gt;.env配置的环境变量。

其中,上面的 maven 命令应该从&lt;filename&gt;.env 设置所有环境变量,然后执行 maven 插件。在 IntelliJ 中,有一个 envFile 插件完全相同。

不想在我的项目中使用特定于环境的属性dev|staging|prod.properties,因为它很混乱且难以管理。我宁愿拥有一个包含所有动态/可变属性的单一环境特定文件filename.env

application.properties

spring:
  cloud:
    config:
      uri: http://config-service:${CONFIG_SERVICE_PORT}
      fail-fast: true
      password: ${CONFIG_SERVICE_PASSWORD}
      username: user

环境文件: .env

CONFIG_SERVICE_PORT=8080
CONFIG_SERVICE_PASSWORD=123

现在,当我在 AWS、GCP 和 Azure 等不同环境中部署应用程序时。我只需要更改.env 文件中的环境变量并运行应用程序java -DenvFile=/path/&lt;fileName&gt;.env -jar application.jar,它就会发挥作用。

我的问题与在dev-mode 中进行测试的maven-sure-fire 插件有关,它需要spring context 的这些环境变量。

任何帮助将不胜感激。

【问题讨论】:

  • 为什么要创建特定的构建环境?无论您在什么环境中运行,Maven 理想情况下都应该运行相同。插件如何从这样的环境变量中受益?你能展示一个用例吗?最后一个问题 - “spring-boot-maven-plugin”与这个问题有什么关系?你有一些具体的用例吗?
  • @MarkBramnik - 不尝试使构建环境特定。请不要将自己与 maven install/deploy/package 命令混淆。这里的意图是将所有动态/可变属性保存在一个位置 .env。因此,即使我在 java -DenvFile=/path/&lt;fileName&gt;.env -jar application.jar 这样的不同环境中运行应用程序,应用程序也会获取所有属性并相应地运行。我只需要为不同的环境更改 .env 即可运行我的应用程序。
  • @MarkBramnik - 使用 maven,问题在于 junit 测试,当您运行上面突出显示的 install/deploy/package 的 maven 命令时,它基本上执行单元/集成测试,并且那些从 .properties 读取值。我不想在我的项目中使用特定于环境的application-&lt;dev|prod|staging&gt;.properties,因为它很乱。我认为最好的方法是保留一个 environmentVariables.env 文件并根据应用程序安装或部署的特定环境更改属性。
  • @MarkBramnik - 你对这个问题有什么想法吗? here.

标签: maven environment-variables maven-plugin spring-boot-maven-plugin


【解决方案1】:

好吧,从您的 cmets 看来,您正在寻找两种不同的解决方案:

  1. 使用java -DenvFile=/path/&lt;fileName&gt;.env -jar application.jar在不同的环境中运行应用程序
  2. 运行测试的解决方案。

这些是不同的问题,我将尝试解决这两个问题

问题 1

当您运行java -jar 时,这意味着工件已经组装好(据我了解,在 spring boot maven 插件的帮助下)。 这个 jar 是一个随时可用的 spring boot 应用程序,maven 在这里基本上是无关紧要的 - maven 是一个构建系统,spring 是一个运行时框架,我们正在谈论运行时。

Spring boot 有很多方法可以实现你想要的。与您的情况接近的“本机”弹簧启动方式是使用“--spring.config.location=file://”和所有必需的配置运行应用程序

看起来像这样(完整文档请参阅here):

java -jar application.jar --spring.config.location=myprops.properties

即使您在src/main/resources/application.properties 中定义了一些属性,此方法也允许有效地覆盖它们,从而提供一种在不同环境中运行不同配置的方法。

这比 .env 文件有一个优势,因为它可以在所有操作系统中以相同的方式运行,甚至在 Windows 中;)因为 Java 是独立于操作系统的 - 我相信它是您可以实现的最好的。

当然,您可以将 java -jar 行包装在某种 bash 脚本中,并在运行 jvm 之前加载/执行一系列 export 命令,但同样,它的“spring-y”方式较少。

问题 2

Maven 以一种与 Spring Boot Maven 插件无关的方式运行测试(单元/集成)。一切都与万无一失/故障安全和 Spring Boot 测试框架有关。

我假设您是在询问集成测试,因为我认为这与单元测试无关,因为它们根本不需要任何环境变量,并且应该在没有 spring 的情况下运行(junit/mockito 应该做工作)

我也会让自己保持这样的假设,即通过 yaml 或属性文件覆盖/配置 Spring Boot 应用程序的方式比 .env 更好,并将在此处提供 Spring 测试配置解决方案:

根据这些假设,您可以在以下路径中创建 yaml 文件:src/test/resources/application-test.yml

此文件可以包含与测试相关的配置,并将覆盖src/main/resources/application.yml 中编写的任何内容。注意,由于application-test.yml 驻留在测试源中,spring boot maven 插件不会将其打包到应用程序中。

根据进行集成测试的具体方式,您还可以考虑使用 @TestPropertySource 注释来提供不遵循 Spring Boot 默认约定的自定义属性/yaml 文件。它对于不使用 spring boot 完整支持引导的 spring 驱动测试特别有用(阅读使用 junit 的 spring runner 但没有注释 @SpringBootTest 的测试)

另一个可能有用的注释是@ActiveProfile("myprofile")。这将导致 Spring Boot 测试自动加载文件src/test/resources/application-myprofile.yml(或application-myprofile.properties

最后但并非最不重要的一点是,我将在源代码中引用带有“dev/prod/staging/properties”的第二条评论。 谈到测试 - 应该只有一个文件application-test.yml。但是请注意,当您使用 yaml 时,可以在同一个文件中定义多个 Spring Boot 配置文件的配置:

# default value
foo:
 bar: 1

---
spring:
  profiles: staging
foo:
  bar: 2

--- 
spring:
  profiles: prod
foo:
  bar: 3

一些相关的SO thread

【讨论】:

  • 感谢您提供宝贵的信息。接受它作为答案,因为它帮助我修复了我的集成测试。我错过了@TestPropertySource,这就是为什么没有选择带有@ActiveProfile("test")application-test.properties 进行集成测试。
  • 您对这个问题有什么想法吗? here.
  • 我认为这取决于测试的具体编写方式,是否有@SpringBootTest 注解,以及是否配置了此注解的哪些属性。如果你想 - 随时问另一个问题(它真的是一个不同的主题)并在此处提供一个链接 - 我会尽力在时间允许的情况下回答
  • 我创建了一个新问题并在我之前的评论中发布了链接。我对用于集成测试的Spring Data mongoDb 属性感到困惑,我想针对具有不同配置的集成测试运行嵌入式 mongoDb。这是有效的,嵌入式 mongoDb 从TestConfig 类的配置开始。并从application-test.properties 为mongoDb 放置@DataMongoTest(excludeAutoConfiguration= {EmbeddedMongoAutoConfiguration.class}) which means it should not read Spring Data` 配置。但不幸的是,这里没有发生这种情况。
猜你喜欢
  • 1970-01-01
  • 2021-10-15
  • 2010-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
  • 1970-01-01
相关资源
最近更新 更多