原文:http://maven.apache.org/pom.html
POM是什么?
POM是“Project ObjectModel”的首字母缩写,即工程对象模型。它在一个名叫pom.xml的文件中使用XML来表示一个Maven工程。在跟使用Maven的人们一起谈论工程时,工程的概念有些哲学的意义,它不仅仅是一个包含代码的文件的集合。一个工程包含了配置文件、相关的开发者和他们的角色、缺陷跟踪系统、组织机构和授权许可、工程的URL、工程依赖、以及所有的其他的对代码发挥作用的微笑片段。它包含相关项目的所有信息。实际上,在Maven的世界里,一个工程可以只是一个pom.xml文件,而不需要包含任何代码。
概要
这是一份POM的<project>元素之下的元素清单,要注意<modelVersion>元素包含了4.0.0。这是当前Maven2和3所支持的唯一POM版本,并且它是必须的。
<projectxmlns="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">
<modelVersion>4.0.0</modelVersion>
<!—基础部分 -->
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<packaging>...</packaging>
<dependencies>...</dependencies>
<parent>...</parent>
<dependencyManagement>...</dependencyManagement>
<modules>...</modules>
<properties>...</properties>
<!—编译设置 -->
<build>...</build>
<reporting>...</reporting>
<!—更多的工程信息 -->
<name>...</name>
<description>...</description>
<url>...</url>
<inceptionYear>...</inceptionYear>
<licenses>...</licenses>
<organization>...</organization>
<developers>...</developers>
<contributors>...</contributors>
<!—环境设置 -->
<issueManagement>...</issueManagement>
<ciManagement>...</ciManagement>
<mailingLists>...</mailingLists>
<scm>...</scm>
<prerequisites>...</prerequisites>
<repositories>...</repositories>
<pluginRepositories>...</pluginRepositories>
<distributionManagement>...</distributionManagement>
<profiles>...</profiles>
</project>
基础部分
POM包含一个工程所需要的所有的信息,以及在编译过程中所使用的插件的配置信息。它是一份有效的“是谁(who)”、“在那儿(where)”、“做了什么(what)”的声明,同时也“在什么时候”、“怎样做”的编译生命周期。这不是说POM不能影响到编译生命周的流程---它是可以的。例如,通过配置<maven-antrun-plugin>元素,就可以有效的把一个ant任务嵌入到POM内部。但是它是最后的声明。跟build.xml准确的告诉ant什么时候运行,做什么事情一样,POM也会写明这些配置(声明)。如果由于一些外部原因导致生命周期跳过ant插件的执行,它不会终止插件的执行过程,这一点跟ant的build.xml不一样,build.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">
<modelVersion>4.0.0</modelVersion>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-project</artifactId>
<version>1.0</version>
</project>
Maven的坐标
上面定义了一个Maven2和3所允许的最小的POM。groupId、artifactId、version是必须的字段(尽管groupId和version不需要显示的定义,因为它们可以继承父辈的这两字段,关于继承后续会更详细的介绍)。这三个字段就像一个地址和时间戳,它在一个资源库中标记了一个特定的位置,就像一个坐标系统。
groupId:通常在组织或工程之中,这个值是唯一的。例如核心的Maven部件都放在groupId是org.apache.maven的下面。这个ID值不一定使用圆点符号来分割,例如,Junit工程。注意,使用圆点符号的groupId不必与工程中所包含的包的结构一致,但是保持一致是一钟好的习惯。当把工程保存到一个存储库中的时候,这个groupId就像操作系统中的Java包的结构一样,圆点会被操作系统的目录分割符(如Unix中的’/’)所替代,这样它就会成为相对于基础库的目录结构,如上文给出的例子中,org.codehaus.mojo组位于目录$M2_REPO/org/codehaus/mojo中。
artifactId:通常artifactId就是该工程的名字,尽管groupId是重要的,但是人们在讨论中很少会提及它(它们经常都是相同的,例如Codehaus Mojo工程的groupId都是org.codehaus.mojo)。artifactId跟在groupId的后面,它跟groupId一起创建了一个把本工程与世界上其他工程分离的唯一的键。groupId和artifactId一起定义了该部件在存储库中的位置。在上面的例子中,my-project位于$M2-REPO/org/codehaus/mojo/my-project中。
version:这是pom.xml命名中最后一部分,groupId:artifactId代表了一个独立的工程,但它们不能描述工程自身的变化。我想一下今天的junit:junit(版本4)跟四年前的版本(版本2)会一样吗?简而言之,代码发生了改变,这些改变是用版本来区分的,并且它会保持线性的增长。在一个部件库中,它会使用版本来进行彼此的区分。my-project的版本1.0的文件会位于目录结构$M2-REPO/org/codehaus/mojo/my-project/1.0中。
以上3个元素指明了一个工程的版本,这样Mave就会知道我们正在处理的工程,以及它们所处的生命周期。
packaging:在给出了groupId:artifactId:version的地址结构后,我们就有了一个真实完整的标准的地址标签。packaging则指定了工程部件的类型。在上述示例中,POM给org.codehaus.mojo:my-project:1.0定义了程序包的类型为jar。我们也可以通过声明不同的packaging让它打包成war文件:
<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">
...
<packaging>war</packaging>
...
</project>
当没有声明packaging时,Maven会假设默认的部件类型是jar。有效的类型是org.apache.maven.lifecycle.mapping.LifecycleMapping组件的Plexus的任务提示。当前核心的packaging值包括:pom、jar、maven-plugin、ejb、war、ear、rar、par。它们用详细的包的结构定义了每个对应的编译动作所要执行的默认的目标列表。
有些时候我们会看到Maven打印出的工程坐标:groupId:artifactId:packaging:version。
classifier:你偶尔会在Maven坐标中看到第五个元素:classifier。稍后我们会介绍它,它会作为工程的类型来显示:groupId:artifactId:packaging:classifier:version。