用 maven filter 管理不同环境的配置文件

使用 maven profile

一个项目可以部署在不同的环境当中,maven 的 profile 针对不同的环境指定各自的编译方法。在 pom.xml 的 profile 中,可以根据不同的环境定制以下内容:

  • <repositories>
  • <pluginRepositories>
  • <dependencies>
  • <plugins>
  • <properties>
  • <dependencyManagement>
  • <distributionManagement>
  • <build>
    • <defaultGoal>
    • <resources>
    • <testResources>
    • <finalName>

可以设置默认激活的 profile

<profiles>
<profile>
<id>profile-1</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
...
</profile>
</profiles>

build 配置项

build 配置项可以在两处出现:

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<!-- 项目级别的构建,基础配置 -->
<build>...</build> <profiles>
<profile>
<!-- 特殊的构建 -->
<build>...</build>
</profile>
</profiles>
</project>

以下是 build 的详细配置

<build>
<defaultGoal>install</defaultGoal>
<directory>${basedir}/target</directory>
<finalName>${artifactId}-${version}</finalName>
<filters> <!-- 过滤器,用于过滤resource中的各个文件 -->
<filter>filters/filter1.properties</filter>
</filters>
<resources>
<resource>
<targetPath>META-INF/plexus</targetPath>
<filtering>false</filtering> <!-- 是否使用过滤器 -->
<directory>${basedir}/src/main/plexus</directory>
<includes>
<include>configuration.xml</include>
</includes>
<excludes>
<exclude>**/*.properties</exclude>
</excludes>
</resource>
</resources>
<testResources>
...
</testResources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.0</version>
<extensions>false</extensions> <!-- 是否使用扩展 -->
<inherited>true</inherited> <!-- 是否可继承 -->
<configuration> <!-- 当前插件的配置 -->
<classifier>test</classifier>
</configuration>
<dependencies>...</dependencies>
<executions> <!-- 配置插件在哪个阶段使用 -->
<execution>
<id>echodir</id>
<goals>
<goal>run</goal>
</goals>
<phase>verify</phase>
<inherited>false</inherited>
<configuration>
<tasks>
<echo>Build Dir: ${project.build.directory}</echo>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<sourceDirectory>${basedir}/src/main/java</sourceDirectory>
<scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory>
<testSourceDirectory>${basedir}/src/test/java</testSourceDirectory>
<outputDirectory>${basedir}/target/classes</outputDirectory>
<testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory>
<extensions> <!-- 通过扩展来修改插件的行为 -->
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ftp</artifactId>
<version>1.0-alpha-3</version>
</extension>
</extensions>
</build>

filter 规则

maven 通过过滤器来修改部署时的不同配置。部署时的所有资源的配置,如果根据环境不同,有不同的配置,则需要在资源中加上以下形式的标记:

${tag.subtag}

如,在 spring.xml 中要配置上传文件的路径:

<beans>
<bean id="uploadService" class="com.oist.project.service.UploadServiceImpl">
<property name="uploadDir" value="${spring.uploadDir}"/>
</bean>
</beans>

在 pom.xml 中进行以下配置:

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<build>
<filters> <!-- 指定 filter -->
<filter>src/main/filters/${deploy.env}.properties</filter>
</filters>
<resources>
<resource> <!-- spring.xml 应该在 src/main/resource 目录下 -->
<filtering>true</filtering> <!-- 是否使用过滤器 -->
</resource>
</resources>
</build> <profiles>
<profile>
<id>development</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<propertys>
<deploy.env>develop</deploy.env>
</propertys>
</profile> <profile>
<id>test</id>
<propertys>
<deploy.env>test</deploy.env>
</propertys>
</profile> <profile>
<id>production</id>
<propertys>
<deploy.env>production</deploy.env>
</propertys>
</profile> </profiles>
</project>

然后就可以针对不同的环境设置不同的目录了:

src/main/filters/develop.properties 文件

# 上传路径:
spring.uploadDir=c:/uploadDir

src/main/filters/test.properties 文件

# 上传路径:
spring.uploadDir=/tmp/upload_dir

src/main/filters/production.properties 文件

# 上传路径:
spring.uploadDir=/app/project/upload_dir

如果配置了多个 filter,并且两个 filter 中有相同的 key,则后面的 value 为最终取值。

<build>
<filters>
<filter>src/main/filters/production.properties</filter>
<filter>src/main/filters/test.properties</filter>
</filters>
</build>

如以上的配置,因为 test.properties 在最后,因而 spring.uploadDir 为 test.properties 的取值 /tmp/upload_dir

maven 的 properties 加载顺序

  1. <build><filters> 中的配置
  2. pom.xml 中的 <properties>
  3. mvn -Dproperty=value 中定义的 property

相同 key 的 property,以最后一个文件中的配置为最终配置。

利用这一规则,可以在打升级 war 包的时候,不将 lib/*.jar 打进 war 包。

<project>
...
<properties>
<lib.exclude>abc.jar</lib.exclude>
</properties>
...
<build>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<packagingExcludes>WEB-INF/lib/${lib.exclude}.jar</packagingExcludes>
</configuration>
</plugin>
</build>
</project>

打第一个 war 包的时候,可以使用以下命令:

mvn clean compile war:war -Pproduction

今后要升级,不用再把 lib 打进 war 包(这样可以使得 war 包体积减少很多),可以使用以下的命令:

mvn clean compile war:war -Pproduction -Dlib.execlude=*
上一篇:top


下一篇:云计算三种服务模式SaaS、PaaS和IaaS及其之间关系(顺带CaaS、MaaS)