转载

Maven学习笔记三【POM文件】

项目对象模型或POM是Maven中的基本工作单元。它是一个XML文件,包含Maven用于构建项目的项目信息和配置细节。它包含大多数项目的默认值。例如构建目录, target 目录,源代码目录 src/main/java ,测试源代码目录 src/test/java 等。在执行任务或目标时,Maven在当前目录中查找pom文件。读取pom,获取需要的配置信息,然后执行目标。

在pom中可以指定的信息有项目依赖项、执行的插件或目标、构建配置文件等。还可以指定项目版本、描述、开发人员、邮件列表等其他信息。

Super POM

Super POM是Maven的默认POM。除非显示设置,否则所有的pom都扩展Super POM。这意味着Super POM中指定的配置,将由我们创建的项目的pom继承。Super POM的代码片段参照 官网 。

Minimal POM

POM的配置的最低要求如下:

  • project root
  • modelVersion - 需要被设置成4.0.0
  • groupId - 项目组织的ID
  • artifactId - 项目的ID
  • version - 项目的版本号

示例:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
</project>

POM需要配置其groupId、artifactId和version。这三个值构成了项目的完全限定名,以 <groupId>:<artifactId>:<version> 的形式出现。对于上面的例子,它的完全限定名是“com.mycompany.app:my-app:1”。

如果没有指定配置细节,Maven将使用它们的默认值,这些默认值之一是打包类型。每个Maven项目都有一种打包类型如果POM中没有指定它,那么将使用默认值“jar”。

此外,我们看到最小POM中没有指定存储库。如果使用最小POM构建项目,它将继承Super POM中的存储库配置。因此,当Maven看到最小POM中的依赖项时,它知道这些依赖项将从Super POM指定的路径 http://repo.maven.apache.org/maven2 下载。

项目继承

POM中合并的元素如下:

  • dependencies
  • developers and contributors
  • plugin lists (including reports)
  • plugin executions with matching ids
  • plugin configuration
  • resources

Super POM是项目继承的一个例子,但是我们也可以通过指定pom中的parent标签来引入自己的父POM,如下面的示例所示。

Example 1

场景

例如,我们重用以前的项目com.mycompany.app:my-app:1,并且引入另一个项目com.mycompany.app:my-module:1。

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-module</artifactId>
  <version>1</version>
</project>

让我们指定他们的目录结构如下:

.
 |-- my-module
 |   `-- pom.xml
 `-- pom.xml

注意: my-module/pom.xml 是com.mycompany.app:my-module:1的POM,而 pom.xml 是com.mycompany.app:my-app:1的POM。

解决方案

现在,我们将com.mycompany.app:my-app:1转变为com.mycompany.app:my-module:1的父项目,修改com.mycompany.app:my-module:1’的pom.xml如下:

<project>
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-module</artifactId>
  <version>1</version>
</project>

注意,我们现在有了一个添加的部分,parent标签。这个部分允许指定哪个项目是我们POM的父项目,我们通过指定父POM的完全限定名来实现这一点。过这个设置,我们的模块现在可以继承父POM的一些属性。

或者,如果我们希望模块的groupId或version与父模块相同,可以删除模块POM中的groupId和version标签:

<project>
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <artifactId>my-module</artifactId>
</project>

Example 2

场景

尽管如果父项目已经安装到本地存储库中,或者在特定的目录结构中(模块的目录为父POM的子目录),上面的配置方式是可行的。但是如果父项目还没安装,并且目录结构与下面的示例一样,该怎么办呢?

.
 |-- my-module
 |   `-- pom.xml
 `-- parent
     `-- pom.xml

解决方案

要处理这个目录结构,需要将 <relativePath> 标签添加到parent部分:

<project>
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
    <relativePath>../parent/pom.xml</relativePath>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <artifactId>my-module</artifactId>
</project>

顾名思义,它是模块pom.xml对于父pom.xml的相对路径。

项目聚合

项目聚合类似于项目继承。但它不是从模块指定父POM,而是从父POM指定模块。通过这样,父项目知道了它的模块,如果对父项目调用Maven命令,那么命令也会执行到父项目的各个模块。要进行项目聚合,需要做如下:

  • 将父项目的打包类型改为pom
  • 在父POM中指定模块

Example 3

场景

沿用上面的POM和目录结构:

com.mycompany.app:my-app:1的POM

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
</project>

com.mycompany.app:my-module:1的POM

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-module</artifactId>
  <version>1</version>
</projec

目录结构如下:

.
 |-- my-module
 |   `-- pom.xml
 `-- pom.xml

The Solution

如果要将my-module聚合到my-app中,只需要修改my-app即可。

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
  <packaging>pom</packaging>
 
  <modules>
    <module>my-module</module>
  </modules>
</project>

如上,增加了 <packaging><modules> 部分。现在,每当Maven命令处理com.mycompany.app:my-app:1时,相同的命令会在com.mycompany.app:my-module:1 上运行。另外,一些命令以不同的方式处理命令聚合。

Example 4

场景

同样,如果我们将目录结构更改为以下形式会怎样呢?

.
 |-- my-module
 |   `-- pom.xml
 `-- parent
     `-- pom.xml

父POM如何指定它的模块?

解决方案

与之前差不多,指定模块的路径:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
  <packaging>pom</packaging>
 
  <modules>
    <module>../my-module</module>
  </modules>
</project>

项目继承 VS 项目聚合

如果有几个Maven项目,并且他们都有相似的配置,那么可以通过提取这些相似的配置并创建父项目来重构项目。因此,需要做的是让Maven项目继承父项目,然后这些配置将适用于所有项目。

如果有一组一起构建或处理的项目,可以创建一个父项目,并声明这些项目是父项目的模块。通过这样,我们只需要构建父类,其他的会随之构建好。

当然,我们可以同时拥有项目继承和聚合。这意味着,可以让模块们指定一个父项目;同时,让该父项目指定那些项目为它的模块。需要遵循如下三条规则:

  • 在每个子POM中指定它们的父POM是谁
  • 将父pom的打包类型更改为值“pom”
  • 在父POM中指定其模块的目录

Example 5

场景

依旧使用上面的POM:

com.mycompany.app:my-app:1的POM

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
</project>

com.mycompany.app:my-module:1的POM

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-module</artifactId>
  <version>1</version>
</project>

目录结构如下:

.
 |-- my-module
 |   `-- pom.xml
 `-- parent
     `-- pom.xml

解决方案

同时进行项目继承和聚合

com.mycompany.app:my-app:1的POM

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1</version>
  <packaging>pom</packaging>
 
  <modules>
    <module>../my-module</module>
  </modules>
</project>

com.mycompany.app:my-module:1的POM

<project>
  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1</version>
    <relativePath>../parent/pom.xml</relativePath>
  </parent>
  <modelVersion>4.0.0</modelVersion>
  <artifactId>my-module</artifactId>
</project>

注意:Profile的继承与用于POM本身的继承策略相同。

项目插值和变量

Maven鼓励的实践之一是不要重复自己的操作。但是,在某些情况下,您需要在几个不同的位置使用相同的值。为了帮助确保值只指定一次,Maven允许在POM中使用自己的变量和预定义的变量。

例如,访问 project.version 变量,可以这样引用:

<version>${project.version}</version>

需要注意的一个因素是,这些变量是在继承之后处理的。这意味着,如果父项目使用变量,那么最终使用的将是它在子项目中的定义,而不是父项目中的定义。

可用变量

项目模型变量

模型中单个值元素的任何字段都可以作为变量引用。例如, ${project.groupId}${project.version}${project.build.sourceDirectory} 等。参阅POM引用以查看完整的属性列表。

特殊变量

属性 解释
project.basedir 当前项目所在目录
project.baseUri 当前项目所在目录,表示为URI。>=Maven2.1
maven.build.timestamp 表示构建开始的时间戳。>=Maven2.1.0-M1

构建时间戳的格式可以通过声明 property maven.build.timestamp 来定制。格式如下:

<project>
  ...
  <properties>
    <maven.build.timestamp.format>yyyy-MM-dd'T'HH:mm:ss'Z'</maven.build.timestamp.format>
  </properties>
  ...
</project>

属性

可以将任何属性定义为变量,考虑如下的例子:

<project>
  ...
  <properties>
    <mavenVersion>2.1</mavenVersion>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-artifact</artifactId>
      <version>${mavenVersion}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.maven</groupId>
      <artifactId>maven-project</artifactId>
      <version>${mavenVersion}</version>
    </dependency>
  </dependencies>
  ...
</project>
原文  http://bboyjing.github.io/2018/12/22/Maven学习笔记三【POM文件】/
正文到此结束
Loading...