【问题标题】:Using Maven for multiple deployment environment (production/development)使用 Maven 进行多种部署环境(生产/开发)
【发布时间】:2010-11-12 01:41:43
【问题描述】:

我在 Maven 中有一个具有默认目录结构的 Web 应用程序。那里没问题。 默认目录结构有一些属性文件指向我的本地主机数据库。

目前我创建了一个 Ant 脚本来创建不同的战争文件 - 一个用于生产,一个用于开发,使用以下命令:

ant deploy-dev
ant deploy-prod
ant deploy-sit
ant deploy-uat

所以基本上他们创建了一个war文件,然后通过插入属性文件来更新war文件

maven 中是否有类似的东西(根据配置创建不同的战争)?

如果是这样,我该怎么做?

我试过mvn war但它只会制造一场战争

【问题讨论】:

  • 您可以为 maven war 插件配置多个执行和关联的分类器,这会从一次运行中生成多个 war 文件,每个文件都适当地命名。见stackoverflow.com/questions/3866784/…

标签: maven-2


【解决方案1】:

我更喜欢在这种情况下使用 maven 配置文件。 例如我们有目录结构:

源/主/资源 | +- 本地 | | | `-特定的.properties +- 开发 | `-特定的.properties

在 pom.xml 中定义两个配置文件:

<profiles>
    <profile>
        <id>local</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <build>
            <resources>
                <resource>
                    <directory>src/main/resources/local</directory>
                </resource>
            </resources>
        </build>
    </profile>
    <profile>
        <id>dev</id>
        <build>
            <resources>
                <resource>
                    <directory>src/main/resources/dev</directory>
                </resource>
            </resources>
        </build>
    </profile>
</profiles>

在这种情况下,我不需要每次更新 pom.xml 以获取新文件。在 IDE 中只需切换配置文件,或从命令行使用 -P 标志。

UPD:如果配置的某些属性相同怎么办? 像这样进行配置:

<profiles>
    <profile>
        <id>local</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <build>
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                </resource>
                <resource>
                    <directory>src/main/config/local</directory>
                </resource>
            </resources>
        </build>
    </profile>
    <profile>
        <id>dev</id>
        <build>
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                </resource>
                <resource>
                    <directory>src/main/config/dev</directory>
                </resource>
            </resources>
        </build>
    </profile>
</profiles>

公共部分将存储在src/main/resources 中,其他配置将在配置目录的适当文件夹中。

【讨论】:

  • 很好的例子,正是我在尝试学习 maven 时所寻找的!谢谢
  • Maven 资源插件根据target/ 中的文件检查时间戳,并且仅在文件较新时复制。切换配置文件时始终运行 mvn clean,否则为 maven 资源插件设置 &lt;overwrite&gt;true&lt;/overwrite&gt;
  • 太棒了!如何在 Spring STS 包中切换配置文件,有什么想法吗?
【解决方案2】:

仅供参考的最佳做法是不必为不同的环境重建您的工件 - 因为这不会导致可重新生成的构建,并且在重建时其他事情可能会发生变化。 IE。如上所述,使用资源过滤仅在重新构建您的项目时有效。

当您将工件从开发到测试或验收测试到生产时 - 您想要重建。

您想要做的实际上是让您的配置动态化,依赖于运行时变量。 IE。针对不同环境的不同弹簧设置或属性文件,例如:

db-dev.properties
db-test.properties
db-prod.properties

然后您可以使用运行时变量和 Spring 的PropertyPlaceholderConfigurer 在这些配置之间切换。

您实际上也可以使用不同的 spring 配置文件,就像我过去所做的那样,进行更复杂的设置。

我还建议您将“默认”设置保留为生产环境 - 这样,如果您部署到生产环境,您无需担心忘记设置环境变量。

【讨论】:

  • 我同意不必重建人工制品以从开发转移到生产。如何让 spring 在运行时根据运行时变量(比如系统属性)加载不同的上下文?
  • 由于这个问题出现在用于分离开发和生产环境的搜索结果的顶部附近,因此这里值得注意的是 Spring 3.1 (relevant announcement) 中的 &lt;beans profile="..."&gt; 属性允许非常简单的条件加载bean 基于环境变量。
  • 当您为公共分发构建工件并且在您的 jar 中将存储生产数据库的凭据时,这种做法将没有用。再说一遍 - 您需要构建单独的项目并将它们放到私有和公共存储库中。
  • 1/ 属性文件必须是可编辑的。所以我们不希望他们被困在 jar/war 中。我更喜欢从外部文件夹加载它们。 2/ 我看不出如何不为不同的环境重建。我们不希望我们的生产版本中没有 H2 数据库、LDAP 嵌入式服务器或其他开发依赖项。
  • @Antony Stubbs 如果我们使用 PropertyPlaceholderConfigurer,我们会将这三个属性文件映射到 3 个 DTO 对吗?
【解决方案3】:

如果您想从流程中删除 ant,我会考虑使用带有过滤器的构建配置文件。

在这种情况下,将您的属性文件插入到 src/main/resources 树结构中。然后使用如下过滤器属性参数化属性文件:

jdbc.url=${filtered.jdbc.property}

然后在 src/main/filters 中根据配置文件创建过滤器文件。所以你可以有 dev-filters.properties sat-filters.properties 等。这些包含:

filtered.jdbc.property=jdbc url here

然后,您为每个区域设置构建配置文件,其中您设置了一个指向您的建筑物的特定区域的 env 属性。然后,您可以设置资源过滤器以对每个构建使用 ${env}-filters.properties。此外,您可以设置 war 插件以将 env 属性添加到您的工件中,以便您实际上将 4 个不同的工件存储在您的存储库中的不同分类器下。

然后,您只需使用每个配置文件构建应用即可。您必须为每个配置文件调用构建,但它确实运行良好。

POM 中的一些设置示例:

<build>
  <filters>
    <filter>src/main/filters/filter-${env}-application.properties</filter>
  </filters>
  <resources>
    <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
    </resource>
  </resources>
  <plugins>
    <plugin>
      <artifactId>maven-war-plugin</artifactId>
      <version>2.1-beta-1</version>
      <executions>
        <execution>
          <phase>package</phase>
          <goals>
            <goal>war</goal>
          </goals>
          <configuration>
            <classifier>${env}</classifier>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

<profiles>
  <profile>
    <id>LOCAL</id>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
      <env>LOCAL</env>
    </properties>
  </profile>
  <profile>
    <id>DEV</id>
    <properties>
      <env>DEV</env>
    </properties>
  </profile>
  <profile>
    <id>UAT</id>
    <properties>
      <env>UAT</env>
    </properties>
  </profile>
  <profile>
    <id>PROD</id>
    <properties>
      <env>PROD</env>
    </properties>
  </profile>
</profiles>

另外,这个blog post 的道具是我最初找到完成此操作的步骤的地方。

【讨论】:

  • 这行得通,但我认为像 Antony Stubbs 建议的那样,在任何地方部署一个人工制品要好得多。在较大的软件项目中,您将拥有许多部署这些东西的环境(生产、测试​​、开发环境、每台开发人员机器),并且为每个环境构建不同的 WAR 是一件很痛苦的事情。
  • 嗯,这取决于。使用 Hudson 为每个地区构建不同的战争很简单。我只是复制配置,创建一个新的夜间构建并更改它构建的配置文件。这些构建被部署到 Nexus,这意味着如果有人想要它,他们可以从 Nexus 中提取或查看 Hudson 以了解它的作用。如果您不使用 CI 系统,我可以看到它可能会很痛苦。我发现风险非常低,因为我要更改的只是属性文件......其他一切都是在不同的 Maven 项目中测试过的 jar。
【解决方案4】:

我已经使用 Spring 的 PropertyPlaceholderConfigurer 处理了这个问题,并在类路径中包含属性文件,在文件系统中包含一个属性文件:

<context:property-placeholder 
    location="classpath*:META-INF/spring/*.properties,file:myapp*.properties"/>

如果在应用启动(或运行测试等)时当前目录中有 myapp*.properties 文件,它将覆盖烘焙到 war/ear/whatever 中的文件的属性。

【讨论】:

    【解决方案5】:

    在 maven 2 上使用 build profiles 有关于它的 this article。看起来它只是通过 antrun 插件委托给 ant,因此您甚至可以重新使用现有的 build.xml 文件。

    【讨论】:

      【解决方案6】:

      这很好地说明了它,使用@seth 提到的构建配置文件-

      http://maven.apache.org/guides/mini/guide-building-for-different-environments.html

      【讨论】:

        【解决方案7】:

        现在有一个插件可以帮助简化这种疯狂。

        https://environments-maven-plugin.sourceforge.io/index.html

        披露。我已经编写了插件。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-27
          • 2014-08-02
          • 2019-11-06
          • 1970-01-01
          • 2010-12-13
          • 2012-08-03
          相关资源
          最近更新 更多