将Maven用于多个部署环境(生产/开发)

时间:2009-07-19 06:27:21

标签: maven-2

我在Maven中有一个带有默认目录结构的Web应用程序。没问题。 默认目录结构有一些指向我的localhost数据库的属性文件。

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

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

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

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

如果是的话,我该怎么做?

我试过mvn war,但它只是创造了一场战争

7 个答案:

答案 0 :(得分:67)

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

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

您想要做的是,您的配置实际上是动态的,取决于运行时变量。即不同环境的不同弹簧设置或属性文件,例如:

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

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

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

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

答案 1 :(得分:62)

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

src/main/resources
|
+- local
|  |
|  `- specific.properties
+- dev
   |
   `- specific.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中,其他配置将存放在config目录中的相应文件夹中。

答案 2 :(得分:19)

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

在此方案中,将属性文件插入src / main / resources树结构中。然后使用如下过滤器属性参数化属性文件:

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

然后在src / main / filters内​​部根据配置文件创建过滤器文件。所以你可以有dev-filters.properties sit-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,这是我最初找到完成此任务的步骤。

答案 3 :(得分:6)

我使用Spring的PropertyPlaceholderConfigurer处理了这个问题,包括类路径上的属性文件和文件系统上的属性文件:

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

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

答案 4 :(得分:4)

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

答案 5 :(得分:1)

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

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

答案 6 :(得分:0)

有一个插件可以帮助简化这种疯狂的行为。

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

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