POM( Project Object Model,项目对象模型 ) 是 Maven 工程的基本工作单元,是一个 XML 文件,包含了项目的基本信息,用于描述项目如何构建,声明项目依赖。
POM 中可以指定以项目依赖,插件,执行目标,项目构建 profile,项目版本,项目开发者列表,相关邮件列表信息。
所有 POM 文件都需要 project 元素和三个必需字段:groupId,artifactId,version。

1.Minimal POM

最小 POM 需要 project 根标签和项目描述。

<!-- 工程根标签 -->
<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">

<!-- 模型版本,对于Maven2及Maven 3来说,它只能是4.0.0 -->
<modelVersion>4.0.0</modelVersion>

<!-- 公司或者组织的唯一标志 -->
<groupId>com.companyname.project-group</groupId>

<!-- 项目的唯一ID,一个groupId下面可能多个项目,就是靠artifactId来区分的 -->
<artifactId>project</artifactId>

<!-- 工程版本号,区分同一个artifact的不同版本 -->
<version>2.2.6.RELEASE</version>

<!--项目产生的构件类型,包括jar、war、ear、pom等 -->
<packaging>jar</packaging>
</project>

2.父(Super)POM

父(Super)POM 是 Maven 默认的 POM。所有的 POM 都继承自一个父 POM,包含了一些可以被继承的默认设置。

<!-- 父项目工程模板 -->
<project>
<!--依赖和扩展的远程仓库列表。 -->
<repositories/>
<!--插件的远程仓库列表,这些插件用于构建和报表 -->
<pluginRepositories/>
<!--构建项目需要的信息 -->
<build/>
<!--子项目可以引用的默认插件信息 -->
<pluginManagement/>
<!--报表规范-->
<reporting/>
<!--项目构建模板-->
<profiles/>
</project>

3.POM 标签详解

基于 POM 项目的基本<project/>结构,引入不同的标签定义不同的项目信息

parent

parent 元素可以指定父 pom。用户可以通过增加 parent 元素来自定义一个父 pom,从而继承该 pom 的配置。parent 元素中包含一些子元素,用来定位父项目和父项目的 pom 文件位置。

<!--父项目的坐标 -->
<!--如果项目中没有规定某个元素的值,那么父项目中的对应值即为项目的默认值 -->
<parent>
<!--被继承的父项目的构件标识符 -->
<artifactId>com.companyname.project-group</artifactId>
<!--被继承的父项目的全球唯一标识符 -->
<groupId>base-project</groupId>
<!--被继承的父项目的版本 -->
<version>1.0.1-RELEASE</version>
<!-- 父项目的pom.xml文件的相对路径,默认值是../pom.xml。 -->
<relativePath>../pom.xml</relativePath>
</parent>

生成文档相关的元素

maven 可以通过 mvn site 命令生成项目的相关文档,包括 name,url,和 description。

<!--项目的名称, Maven产生的文档用 -->
<name>kevin-maven</name>
<!--项目主页的URL, Maven产生的文档用 -->
<url>http://www.xxxxx.com/kevin</url>
<!-- 项目的详细描述, Maven 产生的文档用 -->
<description>A maven project to study maven.</description>

issueManagement 项目的描述性信息

问题管理

<!--项目的问题管理系统-->
<issueManagement>
<!--问题管理系统的名字, -->
<system>question</system>
<!--该项目使用的问题管理系统的URL -->
<url>http://xxxxx.com/question</url>
</issueManagement>

开发者和贡献列表

<!--项目开发者列表 -->
<developers>
<!--某个项目开发者的信息 -->
<developer>
<id/>
<name/>
<email/>
<url />
<roles>
<role>Project Manager</role>
<role>Architect</role>
</roles>
<organization/>
<organizationUrl/>
<!--项目开发者属性 -->
<properties>
<dept>No</dept>
</properties>
<!--项目开发者所在时区 -->
<timezone/>
</developer>
</developers>
<!--项目的其他贡献者列表 -->
<contributors>
<!--见developers/developer元素 -->
...
</contributors>

license 许可

<licenses>
<license>
<name/>
<!--官方的license正文页面的URL -->
<url/>
<!--项目分发的主要方式-->
<distribution>repo</distribution>
<!--关于license的补充信息 -->
<comments/>
</license>
</licenses>

SCM 代码库控制管理

<!--SCM(Source Control Management)标签允许你配置你的代码库,供Maven web站点和其它插件使用。 -->
<scm>
<!--SCM的URL,该URL描述了版本库和如何连接到版本库。该连接只读 -->
<connection>scm:svn:http://...</connection>
<!--给开发者使用的,类似connection元素。即该连接不仅仅只读 -->
<developerConnection>scm:svn:http://...</developerConnection>
<!--当前代码的标签,在开发阶段默认为HEAD -->
<tag />
<!--指向项目的可浏览SCM库(例如ViewVC或者Fisheye)的URL。 -->
<url>http://...</url>
</scm>

项目组织描述

<!--描述项目所属组织的各种属性。Maven产生的文档用 -->
<organization>
<!--组织的全名 -->
<name>demo</name>
<!--组织主页的URL -->
<url>http://xxx</url>
</organization>

创建时间

<inceptionYear /> //4位数字。当产生版权信息时需要使用这个值

repositories 远程仓库

远程仓库列表的配置,包括 <repositories> 依赖和扩展的远程仓库配置,以及 <pluginRepositories> 插件的远程仓库配置。在本地仓库找不到的情况下,maven 下载依赖、扩展和插件就是从这里配置的远程仓库中进行下载。
其中 release 是稳定版本,一经发布不再修改,想发布修改后的项目,只能升级项目版本再进行发布;snapshot 是不稳定的,一个 snapshot 的版本可以不断改变。项目在开发期间一般会使用 snapshot,更方便进行频繁的代码更新;一旦发布到外部,或者开发基本完成,代码迭代不再频繁,则推荐使用 release。

<!--依赖和扩展的远程仓库列表。 -->
<repositories>
<!--包含需要连接到远程仓库的信息 -->
<repository>
<!-- releases和snapshots两组配置,可以在每个单独的仓库中,为每种类型的构件采取不同的策略 -->
<releases>
<!-- true值为true或者false,表示该仓库是否为下载某种类型构件(发布版,快照版)开启。 -->
<enabled />
<!-- 指定更新发生的频率。Maven会比较本地POM和远程POM的时间戳 -->
<!--选项:always,daily(默认),interval:X(X单位为分钟),或者never。 -->
<updatePolicy />
<!-- 当Maven验证构件校验文件失败时该怎么做。选项:ignore,fail,或者warn -->
<checksumPolicy />
</releases>
<snapshots>
<enabled />
<updatePolicy />
<checksumPolicy />
</snapshots>

<!-- 远程仓库唯一标识符。可以用来匹配在settings.xml文件里配置的远程仓库 -->
<id>name-repository-proxy</id>
<!-- 远程仓库名称 -->
<name>name-repository-proxy</name>
<!-- 远程仓库URL -->
<url></url>
<!-- 用于定位和排序构件的仓库布局类型。可以是default或者legacy -->
<layout>default</layout>
</repository>
</repositories>

<!--发现插件的远程仓库列表,这些插件用于构建和报表 -->
<pluginRepositories>
<pluginRepository>
...
</pluginRepository>
</pluginRepositories>

dependencies 项目依赖

pom 文件中通过 dependencyManagement 来声明依赖,通过 dependencies 元素来管理依赖。

<dependencies>
<dependency>
<!-- 依赖依赖坐标 -->
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact</artifactId>
<version>3.8.1</version>

<!-- 依赖类型,默认类型是jar -->
<type>jar</type>
<!-- 依赖的分类器 -->
<classifier></classifier>

<!-- 被排除的依赖,此元素主要用于解决版本冲突问题 -->
<exclusions>
<exclusion>
<artifactId>spring-core</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
<!-- 可选依赖 -->
<optional>true</optional>

<!--依赖范围,在项目发布过程中,帮助决定哪些构件被包括进来
- compile:默认范围,用于编译
- provided:类似于编译,但支持jdk或者容器提供,类似于classpath
- runtime: 在执行时需要使用
- systemPath: 仅用于范围为system。提供相应的路径
- test: 用于test任务时使用
- system: 需要外在提供相应的元素。通过systemPath来取得
- optional: 当项目自身被依赖时,标注依赖是否传递。用于连续依赖时使用
-->
<scope></scope>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<dependency>
...
</dependency>
</dependencies>
</dependencyManagement>

build 项目构建需要的信息

<build/>元素中包括 directory 路径管理,resource 资源管理,plugin 插件管理,extension 构建扩展等

路径管理

路径管理定义了各种源码和编译结果的输出路径。如果遵循 maven 默认的路径约定,这里的几个元素不需要配置。

<!--项目源码目录,当构建项目的时候,构建系统会编译目录里的源码。该路径是相对于pom.xml的相对路径。 -->
<sourceDirectory />
<!--该元素设置了项目单元测试使用的源码目录。该路径是相对于pom.xml的相对路径 -->
<testSourceDirectory />
<!--被编译过的应用程序class文件存放的目录。 -->
<outputDirectory />
<!--被编译过的测试class文件存放的目录。 -->
<testOutputDirectory />
<!--项目脚本源码目录,该目录下的内容,会直接被拷贝到输出目录,因为脚本是被解释的,而不是被编译的 -->
<scriptSourceDirectory />

resource 资源管理

<resources/>主要是对应用程序 resource 资源和单元测试部分 resource 资源的管理,分别通过 resource 标签和 testResource 标签管理两种资源。两个标签元素可选的子元素都是一样的。

<resources>
<!-- 项目相关或测试相关的所有资源路径 -->
<resource>
<!-- 描述了资源的目标输出路径。该路径是相对于target/classes的路径 -->
<targetPath />
<!--是否使用参数值代替参数名。参数值取自文件里配置的属性,文件在filters元素里列出。 -->
<filtering />
<!--描述存放资源的目录,该路径相对POM路径 -->
<directory />
<!--包含的模式列表,例如**/*.xml,只有符合条件的资源文件才会在打包的时候被放入到输出路径中 -->
<includes />
<!--排除的模式列表,例如**/*.xml,符合的资源文件不会在打包的时候会被过滤掉 -->
<excludes />
</resource>
</resources>
<!-- 单元测试相关的所有资源路径 -->
<testResources>
<testResource>
...
</testResource>
</testResources>

plugin 插件管理

插件包括 <pluginManagement/><plugins/><pluginManagement/> 中有子元素 <plugins/>,主要是用来声明子项目可以引用的默认插件信息,如果只写在 <pluginManagement/> 中是不会被引入的。<project/> 下的直接子元素 <plugins/> 中定义的才是这个项目中真正需要被引入的插件。

 <!-- 子项目可以引用的默认插件信息。pluginManagement中的插件直到被引用时才会被解析或绑定到生命周期 -->
<!-- 这里只是做了声明,并没有真正的引入。给定插件的任何本地配置都会覆盖这里的配置-->
<pluginManagement>
<!-- 可使用的插件列表 -->
<plugins>
<!--plugin元素包含描述插件所需要的信息。 -->
<plugin>
<!--插件定位坐标三元素:groupId + artifactId + version -->
<groupId />
<artifactId />
<version />
<!-- 是否使用这个插件的Maven扩展(extensions),默认为false -->
<!-- 由于性能原因,只有在真需要下载时,该元素才被设置成enabled -->
<extensions />

<!--在构建生命周期中执行一组目标的配置。每个目标可能有不同的配置。 -->
<executions>
<!--execution元素包含了插件执行需要的信息 -->
<execution>
<!--执行目标的标识符 -->
<id />
<!--绑定目标的构建生命周期阶段 -->
<phase />
<!--配置的执行目标 -->
<goals />
<!--配置是否被传播到子POM -->
<inherited />
<!--作为DOM对象的配置 -->
<configuration />
</execution>
</executions>

<!--项目引入插件所需要的额外依赖 -->
<dependencies/>
<!--任何配置是否被传播到子项目 -->
<inherited />
<!--作为DOM对象的配置 -->
<configuration />
</plugin>
</plugins>
</pluginManagement>
<!--project使用的插件列表 -->
<plugins>
<!-- 可选的子元素同上 -->
<plugin/>
</plugins>

extension 构建扩展

<extensions/> 是在此构建中使用的项目的列表,它们将被包含在运行构建的 classpath 中。这些项目可以启用对构建过程的扩展,并使活动的插件能够对构建生命周期进行更改。简而言之,扩展是在构建期间激活的 artifacts。

<extensions>
<extension>
<!--项目坐标三元素:groupId + artifactId + version -->
<groupId />
<artifactId />
<version />
</extension>
</extensions>

其它配置

<!--当项目没有规定目标(Maven2 叫做阶段)时的默认值 -->
<defaultGoal />
<!--构建产生的所有文件存放的目录 -->
<directory />
<!--产生的构件的文件名,默认值是${artifactId}-${version}。 -->
<finalName />
<!--当filtering开关打开时,使用到的过滤器属性文件列表 -->
<filters />

profile 配置

定义项目构建的模板,当有条件被激活时会修改构建处理

<!--在列的项目构建profile,如果被激活,会修改构建处理 -->
<profiles>
<!--根据环境参数或命令行参数激活某个构建处理 -->
<profile>
<!--构建配置的唯一标识符。即用于命令行激活,也用于在继承时合并具有相同标识符的profile。 -->
<id />
<!-- 自动触发profile的条件逻辑 -->
<activation>
<!--profile默认是否激活的标志 -->
<activeByDefault />
<!--当匹配的jdk被检测到,profile被激活 -->
<jdk />
<!--os元素可以定义一些操作系统相关的属性。 -->
<os>
<!--激活profile的操作系统的名字 -->
<name>Windows XP</name>
<!--激活profile的操作系统所属家族(如 'windows') -->
<family>Windows</family>
<!--激活profile的操作系统体系结构 -->
<arch>x86</arch>
<!--激活profile的操作系统版本 -->
<version>5.1.2600</version>
</os>
<!--如果Maven检测到某一个属性,其拥有对应的名称和值,Profile就会被激活 -->
<property>
<!--激活profile的属性的名称 -->
<name>mavenVersion</name>
<!--激活profile的属性的值 -->
<value>2.0.3</value>
</property>
<!--提供一个文件名,通过检测该文件的存在或不存在来激活profile。missing检查文件是否存在,如果不存在则激活profile -->
<!--另一方面,exists则会检查文件是否存在,如果存在则激活profile -->
<file>
<!--如果指定的文件存在,则激活profile。 -->
<exists>/usr/local/abcd/abcd-home/jobs/maven-guide-zh-to-production/workspace/
</exists>
<!--如果指定的文件不存在,则激活profile。 -->
<missing>/usr/local/abcd/abcd-home/jobs/maven-guide-zh-to-production/workspace/
</missing>
</file>
</activation>

<build />
<repositories />
<pluginRepositories />
<dependencies />
<dependencyManagement />
<reporting />
<distributionManagement />
<modules />
<properties />
</profile>
</profiles>

distributionManagement 项目分发信息相关元素

<distributionManagement>
<!--部署项目产生的构件到远程仓库需要的信息 -->
<repository>
<!-- 是分配给快照一个唯一的版本号 -->
<uniqueVersion />
<id>kevin-maven2</id>
<name>kevinmaven2</name>
<url>file://${basedir}/target/deploy</url>
<layout />
</repository>
<!-- 构件临时部署的仓库 -->
<snapshotRepository/>
<repository>
...
<repository/>
</snapshotRepository>

<!--部署项目的网站需要的信息 -->
<site>
<!--部署位置的唯一标识符,用来匹配站点和settings.xml文件里的配置 -->
<id>kevin-site</id>
<!--部署位置的名称 -->
<name>website</name>
<!--部署位置的URL,按protocol://hostname/path形式 -->
<url/>
</site>

<!--项目下载页面的URL。如果没有该元素,用户应该参考主页 -->
<!--本元素是为了帮助定位那些不在仓库里的构件(license限制) -->
<downloadUrl />

<!--如果构件移到了新的位置,这里列出构件的重定位信息 -->
<relocation>
<groupId />
<artifactId />
<version />
<!--显示给用户的,关于移动的额外信息,例如原因 -->
<message />
</relocation>

<!-- 给出该构件在远程仓库的状态。本地项目中不能设置该元素,因为这是工具自动更新的 -->
<!-- 有效的值有:none(默认),converted(仓库管理员从 Maven 1 POM转换过来),
partner(直接从伙伴Maven 2仓库同步过来),deployed(从Maven 2实例部署),
verified(被核实时正确的和最终的) -->
<status />
</distributionManagement>

reporting 报表规范

报表规范描述的是使用 mvn site 命令时使用的一些配置

<!-- 执行"mvn site"运行报表 -->
<reporting>
<!--网站是否排除默认的报表。这包括"项目信息"菜单中的报表。 -->
<excludeDefaults />
<!--所有产生的报表存放到哪里。默认值是${project.build.directory}/site。 -->
<outputDirectory />
<!--使用的报表插件和他们的配置。 -->
<plugins>
<!--plugin元素包含描述报表插件需要的信息 -->
<plugin>
<groupId />
<artifactId />
<version />
<inherited />
<configuration />
<!-- 一组报表的多重规范,每个规范可能有不同的配置。一个规范(报表集)对应一个执行目标 -->
<reportSets>
<!--表示报表的一个集合,以及产生该集合的配置 -->
<reportSet>
<!--报表集合的唯一标识符,POM继承时用到 -->
<id />
<!--产生报表集合时,被使用的报表的配置 -->
<configuration />
<!--配置是否被继承到子POMs -->
<inherited />
<!--这个集合里使用到哪些报表 -->
<reports />
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>

邮件列表

<!--项目相关邮件列表信息 -->
<mailingLists>
<mailingList>
<!--邮件的名称 -->
<name>Demo</name>
<!--发送邮件的地址或链接 -->
<post>kevin@123.com</post>
<!--订阅邮件的地址或链接 -->
<subscribe>kevin@123.com</subscribe>
<!--取消订阅邮件的地址或链接 -->
<unsubscribe>kevin@123.com</unsubscribe>
<!--你可以浏览邮件信息的URL -->
<archive>http:/xxxxxx/kevin/demo/</archive>
</mailingList>
</mailingLists>

ciManagement 持续集成配置

<!--项目持续集成信息 -->
<ciManagement>
<!--持续集成系统的名字,例如continuum -->
<system />
<!--该项目使用的持续集成系统的URL(如果持续集成系统有web接口的话)。 -->
<url />
<!--构建完成时,需要通知的开发者/用户的配置项。包括被通知者信息和通知条件(错误,失败,成功,警告) -->
<notifiers>
<!--配置一种方式,当构建中断时,以该方式通知用户/开发者 -->
<notifier>
<!--传送通知的途径 -->
<type />
<!--发生错误时是否通知 -->
<sendOnError />
<!--构建失败时是否通知 -->
<sendOnFailure />
<!--构建成功时是否通知 -->
<sendOnSuccess />
<!--发生警告时是否通知 -->
<sendOnWarning />
<!--不赞成使用。通知发送到哪里 -->
<address />
<!--扩展配置项 -->
<configuration />
</notifier>
</notifiers>
</ciManagement>

其他配置

<!--描述了这个项目构建环境中的前提条件。 -->
<prerequisites>
<!--构建该项目或使用该插件所需要的Maven的最低版本 -->
<maven />
</prerequisites>
<!--模块被构建成项目的一部分。列出的每个模块元素是指向该模块的目录的相对路径 -->
<modules />

POM 主要配置结构

project: modelVersion, artifactId, packing, version, name, url, description, inceptionYear
|-- prerequisites: maven
|-- *parent: artifactId, groupId, version, relativePath
|-- *repositories: repository
| |-- id, name, url, layout
| release
| |-- enabled, updatePolicy, checksumPolicy
| snapshot
| |-- enabled, updatePolicy, checksumPolicy
|-- *pluginRepositories: pluginRepository(同repositories)
|-- *dependencies: dependency
| |-- artifactId, groupId, version, type, classifier, scope, systemPath, optional
| executions
| |-- exclusion
| |-- artifactId, groupId
|-- *build: sourceDirectory, scriptCourceDirectory, testSourceDirectory, outputDirectory, testOutputDirectory,
| extensions, defaultGoal, directory, finalName, filters
| |-- groupId, artifactId, version
| resources
| |-- resource
| |-- targetPath, filtering, directory, includes, excludes
| testResources
| |-- testResource
| |-- targetPath, filtering, directory, includes, excludes
| pluginManagement
| |-- plugins
| |-- plugin
| |-- groupId, artifactId, version, extensions, inherited, configuration
| executions
| |-- execution
| |-- id, phase, goals, inherited, configuration
| dependencies(同project/dependencies)
| plugins(同pluginManagement/plugins)
|-- *reporting: excludeDefaults, outputDirectory
| plugin
| |-- groupId,artifactId, version, extensions, goals, inherited, configuration
| reportSets
| |-- reportSet
| |-- id, configuration, inherited
|-- *dependencyManagement: dependencie(同project/dependencies)
|-- *distributionManagement: repository, downloadUrl, status
| |-- uniqueVersion, id, name, url, layout
| snaphotRepository
| |-- uniqueVersion, id, name, url, layout
| site
| |-- id, name, url
| relocation
| |-- groupId, artifactId, version, message
|-- *profiles: profile
| |-- id, activation, modules
| |-- activeByDefault, jdk, property,
| os
| |-- name, family, arch, version
| file
| |-- exists, missing
| build(同project/build)
|
|
|-- developers: developer
| |-- id, name, email, url, roles, organization, organizationUrl, properties, timezone
|-- contributors: contributor
| |-- name, email, url, roles, organization, organizationUrl, properties, timezone
|-- licenses: license
| |-- name, url, distribution, comments
|-- scm: connection, developerConnection, tag, url
|-- organization: name, url
|-- mailingLists: mailingList
| |-- name, post, subscribe, unsubscribe, archive
|-- issueManagement: system, url
|-- ciManagement: system, url, notifiers
| |-- type, sendOnError, sendOnFailure, sendOnSuccess, sendOnWarning, address, configuration