11.2. 通过Maven Profiles实现可移植性

Maven中的profile是一组可选的配置,可以用来设置或者覆盖配置默认值。有了profile,你就可以为不同的环境定制构建。profile可以在pom.xml中配置,并给定一个id。然后你就可以在运行Maven的时候使用的命令行标记告诉Maven运行特定profile中的目标。以下pom.xml使用production profile覆盖了默认的Compiler插件设置。

Example 11.1. 使用一个Maven Profile覆盖Compiler插件设置

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.sonatype.mavenbook</groupId>
  <artifactId>simple</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>simple</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <profiles>
    <profile>
      <id>production</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
              <debug>false</debug>
              <optimize>true</optimize>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
</project>

本例中,我们添加了一个名为production的profile,它覆盖了Maven Compiler插件的默认配置,现在仔细看一下这个profile的语法。

1

pom.xml中的profiles元素,它包含了一个或者多个profile元素。由于profile覆盖了pom.xml中的默认设置,profiles通常是pom.xml中的最后一个元素。

2

每个profile必须要有一个id元素。这个id元素包含的名字将在命令行调用profile时被用到。我们可以通过传给Maven一个-P<profile_id>参数来调用profile。

3

一个profile元素可以包含很多其它元素,只要这些元素可以出现在POM XML文档的project元素下面。本例中,我们覆盖了Compiler插件的行为,因此必须覆盖插件配置,该配置通常位于一个build和一个plugins元素下面。

4

我们覆盖了Maven Compiler插件的配置。确保通过production profile产生的字节码不会包含调试信息,并且字节码会被编译器优化。

要使用production profile来运行mvn install,你需要在命令行传入-Pproduction参数。要验证production profile覆盖了默认的Compiler插件配置,可以像这样以开启调试输出(-X) 的方式运行Maven。

~/examples/profile $ mvn clean install -Pproduction -X
... (omitting debugging output) ...
[DEBUG] Configuring mojo 'o.a.m.plugins:maven-compiler-plugin:2.0.2:testCompile'
[DEBUG]   (f) basedir = ~\examples\profile
[DEBUG]   (f) buildDirectory = ~\examples\profile\target
...
[DEBUG]   (f) compilerId = javac
[DEBUG]   (f) debug = false
[DEBUG]   (f) failOnError = true
[DEBUG]   (f) fork = false
[DEBUG]   (f) optimize = true
[DEBUG]   (f) outputDirectory = \
          ~\svnw\sonatype\examples\profile\target\test-classes
[DEBUG]   (f) outputFileName = simple-1.0-SNAPSHOT
[DEBUG]   (f) showDeprecation = false
[DEBUG]   (f) showWarnings = false
[DEBUG]   (f) staleMillis = 0
[DEBUG]   (f) verbose = false
[DEBUG] -- end configuration --
... (omitting debugging output) ...

Maven的调试输出体现了production profile下Compiler插件的配置。可以看到,debug被设置成false,optimize设置成true。

11.2.1. 覆盖一个项目对象模型

虽然前面的样例展示了如何覆盖一个Maven插件的默认配置属性,你仍然没有确切知道Maven profile能覆盖什么。简单的回答这个问题,Maven profile可以覆盖几乎所有pom.xml中的配置。Maven POM包含一个名为profiles的元素,它包含了项目的替代配置,在这个元素下面,每个profile元素定义了一个单独的profile。每个profile必须要有一个id,除此之外,它可以包含几乎所有你能在project下看到的元素。以下的XML文档展示了一个profile允许覆盖的所有的元素。

Example 11.2. Profile中允许出现的元素

<project>
  <profiles>
    <profile>
      <build>
        <defaultGoal>...</defaultGoal>
        <finalName>...</finalName>
        <resources>...</resources>
        <testResources>...</testResources>
        <plugins>...</plugins>
      </build>
      <reporting>...</reporting>
      <modules>...</modules>
      <dependencies>...</dependencies>
      <dependencyManagement>...</dependencyManagement>
      <distributionManagement>...</distributionManagement>
      <repositories>...</repositories>
      <pluginRepositories>...</pluginRepositories>
      <properties>...</properties>
    </profile>
  </profiles>
</project>


一个Profile可以覆盖项目构件的最终名称,项目依赖,插件配置以影响构建行为。Profile还可以覆盖分发配置;例如,如果你通过一个staging profile发布一个构件到staging服务器上,你就可以创建一个profile然后在里面定义distributionManagement元素。