Maven的构建配置文件介绍

Maven的Profile

Posted by qin4zhang on March 7, 2020

注意

想法及时记录,实现可以待做。

Maven作为java的依赖管理和构建打包工具。本文将介绍下pom文件的有关内容。官方文档

Apache Maven竭尽全力确保构建可移植。 除其他外,这意味着允许在POM内部进行配置配置,避免所有文件系统引用(在继承,依赖关系和其他位置),并更加依赖本地存储库来存储实现此目的所需的元数据。

但是,有时不能完全实现可移植性。 在某些情况下,可能需要使用本地文件系统路径来配置插件。 在其他情况下,将需要稍微不同的依赖项集,并且项目的工件名称可能需要稍作调整。 在其他时候,根据检测到的构建环境,您甚至可能需要在构建生命周期中包括整个插件。

为了解决这些情况,Maven支持构建配置文件。 使用POM本身中可用元素的子集(加上一个额外的部分)来指定概要文件,并以多种方式中的任何一种触发概要文件。 它们在构建时修改POM,并且打算在补充集中使用,以为一组目标环境提供等效但不同的参数(例如,在开发,测试和开发过程中提供appserver根的路径) 生产环境)。 因此,概要文件很容易导致团队中不同成员的构建结果不同。 但是,如果使用得当,可以在保持项目可移植性的同时使用配置文件。 这还将最小化maven的-f选项的使用,该选项允许用户创建具有不同参数或配置的另一个POM,这使其更易于维护,因为它仅使用一个POM运行。

配置文件有哪些不同类型?每个定义在哪里?

  • 每个项目
    • 在POM本身(pom.xml)中定义。
  • 每个用户
    • 在Maven设置(%USER_HOME%/.m2/settings.xml)中定义。
  • 全局
    • 在全局Maven设置(${maven.home}/conf/settings.xml)中定义。
  • 配置文件描述
    • 位于基于项目的目录(profiles.xml)中的描述符(在Maven 3.0中不受支持:请参见Maven 3兼容性说明)

如何触发配置? 根据使用的配置文件类型,这有何不同?

可以通过多种方式激活配置文件:

  • 通过命令行
  • 通过Maven的设置
  • 基于环境变量
  • 系统设置
  • 存在或缺少文件

激活配置的详情

可以使用-P命令行标志显式指定配置文件。

该标志后跟逗号分隔的配置文件ID列表。 除了通过其激活配置或settings.xml中的<activeProfiles>部分激活的任何配置文件之外,还激活了在该选项中指定的配置文件。

mvn groupId:artifactId:goal -P profile-1,profile-2

可以通过<activeProfiles>部分在Maven设置中激活配置文件。 本节列出了<activeProfile>元素的列表,每个元素内部都包含一个profile-id。

<settings>
  ...
  <activeProfiles>
    <activeProfile>profile-1</activeProfile>
  </activeProfiles>
  ...
</settings>

默认情况下,每当项目使用<activeProfiles>标记中列出的配置文件时,该配置文件都会被激活。

可以根据检测到的构建环境状态自动触发配置文件。 这些触发器是通过配置文件本身中的<activation>部分指定的。 当前,此检测仅限于JDK版本的前缀匹配,系统属性的存在或系统属性的值。 这里有些例子。

当JDK的版本以”1.4”(例如”1.4.0_08”,”1.4.2_07”,”1.4”)开头时,以下配置将触发配置文件:

<profiles>
  <profile>
    <activation>
      <jdk>1.4</jdk>
    </activation>
    ...
  </profile>
</profiles>

范围也可以从Maven 2.1开始使用(有关更多信息,请参考Enforcer版本范围语法)。 以下是1.3、1.4和1.5版本。

<profiles>
  <profile>
    <activation>
      <jdk>[1.3,1.6)</jdk>
    </activation>
    ...
  </profile>
</profiles>

注意:上限,例如,1.5]可能不包括1.5的大多数发行版,因为它们将具有一个附加的”补丁”发行版,例如_05,而该发行版在上述范围内未考虑在内。

下一个将根据操作系统设置激活。 有关OS值的更多详细信息,请参见Maven Enforcer插件。

<profiles>
  <profile>
    <activation>
      <os>
        <name>Windows XP</name>
        <family>Windows</family>
        <arch>x86</arch>
        <version>5.1.2600</version>
      </os>
    </activation>
    ...
  </profile>
</profiles>

当使用任何值指定系统属性”debug”时,以下配置文件将被激活:

<profiles>
  <profile>
    <activation>
      <property>
        <name>debug</name>
      </property>
    </activation>
    ...
  </profile>
</profiles>

当未定义系统属性”debug”或定义的属性值不是”true”时,将激活以下配置文件。

<profiles>
  <profile>
    <activation>
      <property>
        <name>debug</name>
        <value>!true</value>
      </property>
    </activation>
    ...
  </profile>
</profiles>

要激活它,您可以在命令行中输入以下命令之一:

mvn groupId:artifactId:goal
mvn groupId:artifactId:goal -Ddebug=false

当系统属性”环境”指定为值”test”时,下一个示例将触发概要文件:

<profiles>
  <profile>
    <activation>
      <property>
        <name>environment</name>
        <value>test</value>
      </property>
    </activation>
    ...
  </profile>
</profiles>

要激活它,您可以在命令行中输入:

mvn groupId:artifactId:goal -Denvironment=test

从Maven 3.0开始,还可以基于settings.xml中活动配置文件的属性来激活POM中的配置文件。

注意:环境变量(例如FOO)可以作为env.FOO形式的属性使用。 还要注意,在Windows上,环境变量名称被标准化为全部大写。

当缺少生成的文件target/generate-sources/axistools/wsdl2java/org/apache/maven时,此示例将触发配置文件。

<profiles>
  <profile>
    <activation>
      <file>
        <missing>target/generated-sources/axistools/wsdl2java/org/apache/maven</missing>
      </file>
    </activation>
    ...
  </profile>
</profiles>

从Maven 2.0.9开始,可以对标记<exists><missing>进行插值。 受支持的变量是${user.home}之类的系统属性和${env.HOME}之类的环境变量。 请注意,POM本身定义的属性和值不适用于此处的插值,例如上面的示例激活器无法使用${project.build.directory},但需要对路径target进行硬编码。

默认情况下,配置文件也可以使用以下配置激活:

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

除非使用前面介绍的方法之一激活同一POM中的另一个配置文件,否则此配置文件将对所有版本自动激活。 在命令行上或通过其激活配置激活POM中的配置文件时,默认情况下所有处于活动状态的配置文件都会自动停用。

停用配置文件

从Maven 2.0.10开始,可以使用命令行通过在标识符前面加上字符’!’来停用一个或多个概要文件。 或’-‘,如下所示:

mvn groupId:artifactId:goal -P !profile-1,!profile-2

这可用于停用标记为activeByDefault的配置文件或将通过其激活配置激活的配置文件。

每种配置文件都可以自定义POM的哪些区域? 为什么?

既然我们已经讨论了在哪里指定配置文件以及如何激活它们,那么讨论可以在配置文件中指定的内容将很有用。 与配置文件配置的其他方面一样,此答案也不是那么简单。

根据您选择配置配置文件的位置,您将有权使用各种POM配置选项。

外部文件中的配置文件

从严格意义上讲,外部文件(即settings.xmlprofiles.xml)中指定的配置文件是不可移植的。 似乎很有可能更改构建结果的任何内容都限于POM中的内联配置文件。 诸如存储库列表之类的东西可能只是经过批准的工件的专有存储库,而不会改变构建的结果。 因此,您将只能修改<repositories><pluginRepositories>部分,以及一个额外的<properties>部分。

<properties>部分允许您指定自由格式的键-值对,这些对将包含在POM的插值过程中。 这允许您以${profile.provided.path}的形式指定插件配置。

POM中的配置文件

另一方面,如果可以在POM内合理地指定配置文件,则可以有更多选择。 当然,要权衡的是您只能修改该项目及其子模块。 由于这些配置文件是内联指定的,因此可以更好地保留可移植性,因此可以合理地说,您可以向其中添加更多信息,而不会导致其他用户无法获得该信息。

POM中指定的配置文件可以修改以下POM元素:

  • <repositories>
  • <pluginRepositories>
  • <dependencies>
  • <plugins>
  • <properties>
  • <modules>
  • <reports>
  • <reporting>
  • <dependencyManagement>
  • <distributionManagement>
  • 元素的子集,包括:
    • <defaultGoal>
    • <resources>
    • <testResources>
    • <directory>
    • <finalName>
    • <filters>
    • <pluginManagement>
    • <plugins>

配置文件的顺序

配置文件中POM中的所有文件元素会覆盖具有相同POM名称的全局元素,或者在集合的情况下扩展它们。 如果在同一POM或外部文件中有多个配置文件处于活动状态,则稍后定义的配置文件优先于先前定义的配置文件(与配置文件ID和激活顺序无关)。

比如:

<project>
  ...
  <repositories>
    <repository>
      <id>global-repo</id>
      ...
    </repository>
  </repositories>
  ...
  <profiles>
    <profile>
      <id>profile-1</id>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <repositories>
        <repository>
          <id>profile-1-repo</id>
          ...
        </repository>
      </repositories>
    </profile>
    <profile>
      <id>profile-2</id>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <repositories>
        <repository>
          <id>profile-2-repo</id>
          ...
        </repository>
      </repositories>
    </profile>
    ...
  </profiles>
  ...
</project>

这将导致存储库列表:profile-2-repoprofile-1-repoglobal-repo

如何确定在构建过程中哪些配置文件有效?

确定激活的配置文件将帮助用户了解在构建过程中执行了哪些特定的配置文件。 我们可以使用Maven帮助插件来告诉您在构建过程中哪些配置文件有效。

mvn help:active-profiles

让我们有一些小样本,这些样本将帮助我们更多地了解该插件的主动配置文件目标。

pom.xml中的配置文件的最后一个示例中,您会注意到有两个名为appserverConfig-devappserverConfig-dev-2的配置文件,它们已为属性指定了不同的值。 如果我们继续执行:

mvn help:active-profiles -Denv=dev

结果将是配置文件的ID的项目符号列表,其激活属性为”env=dev”以及声明它的源。 请参阅下面的示例。

The following profiles are active:

 - appserverConfig-dev (source: pom)

现在,如果我们在settings.xml中声明了一个配置文件(请参阅settings.xml中的配置文件示例),并且已将其设置为活动配置文件并执行:

mvn help:active-profiles

结果应该是这样的

The following profiles are active:

 - appserverConfig (source: settings.xml)

即使我们没有激活属性,配置文件也被列为活动状态。 为什么? 就像我们之前提到的,在settings.xml中设置为活动配置文件的配置文件会自动激活。

现在,如果在settings.xml中有一个配置文件,它已被设置为活动配置文件,并且还触发了POM中的配置文件。 您认为哪个配置文件会对构建产生影响?

mvn help:active-profiles -P appserverConfig-dev

这将列出已激活的配置文件:

The following profiles are active:

 - appserverConfig-dev (source: pom)
 - appserverConfig (source: settings.xml)

即使它列出了两个活动配置文件,我们也不确定已应用其中一个。 要查看对构建的影响,请执行:

mvn help:effective-pom -P appserverConfig-dev

这会将针对此构建配置的有效POM打印到控制台。 请注意,settings.xml中的配置文件比POM中的配置文件具有更高的优先级。 因此,此处已应用的配置文件是appserverConfig而不是appserverConfig-dev

如果要将输出从插件重定向到名为effective-pom.xml的文件,请使用命令行选项-Doutput=effective-pom.xml