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

Tit*_*ore 54 maven-2

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

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

ant deploy-dev
ant deploy-prod
ant deploy-sit
ant deploy-uat
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

Ant*_*bbs 70

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

当您将工件从开发用于测试或验收测试到生产时 - 您希望重建.

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

db-dev.properties
db-test.properties
db-prod.properties
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 由于这个问题出现在分离开发和生产环境的搜索结果的顶部附近,因此值得注意的是Spring 3.1中的`<beans profile ="...">属性([相关公告](http:// blog.springsource.com/2011/02/11/spring-framework-3-1-m1-released/))允许基于环境变量进行非常简单的bean加载. (5认同)
  • 当您为公共分发构建工件时,这种做法将无用,并且您将在jar中存储生产数据库的凭据.再次 - 您需要构建单独的项目并将它们放到私有和公共存储库中. (5认同)
  • 1 /属性文件必须是可编辑的.所以我们不希望它们被卡在jar/war中.我更喜欢从外部文件夹加载它们.2 /我看不出如何不为不同的环境重建.我们不希望在生产版本中既没有H2数据库,LDAP嵌入式服务器或其他dev依赖项. (2认同)

m1l*_*1ld 66

我更喜欢在这种情况下使用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>
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我不需要每次更新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>
Run Code Online (Sandbox Code Playgroud)

公共部分将存储在src/main/resources其他配置中,将在config目录中的相应文件夹中.

  • 很棒的例子,正是在我努力学习maven时我正在寻找的东西!谢谢 (3认同)
  • Maven资源插件检查`target /`中的文件的时间戳,并且只在文件较新时才复制.切换配置文件时始终运行`mvn clean`,或者为maven资源插件设置`<overwrite> true </ overwrite>`. (3认同)
  • @Logic见[http://i.giphy.com/l41YnoRCaWa63ERHi.gif ](http://i.giphy.com/l41YnoRCaWa63ERHi.gif) (3认同)

Mik*_*ell 19

如果要从进程中删除ant,我会考虑使用带有过滤器的构建配置文件.

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

jdbc.url=${filtered.jdbc.property}
Run Code Online (Sandbox Code Playgroud)

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

filtered.jdbc.property=jdbc url here
Run Code Online (Sandbox Code Playgroud)

然后,为每个区域设置构建配置文件,在该区域中设置env指向建筑物特定区域的属性.然后,您可以设置资源过滤器以${env}-filters.properties用于每个构建.此外,您可以设置战争插件的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>
Run Code Online (Sandbox Code Playgroud)

此外,这个博客文章的道具,这是我最初找到完成此步骤的步骤.


Dav*_*ker 6

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

<context:property-placeholder 
    location="classpath*:META-INF/spring/*.properties,file:myapp*.properties"/>
Run Code Online (Sandbox Code Playgroud)

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