POM是Project Object Model的缩写,是Maven工作的基础单元;POM.xml是一个包含关于Maven项目信息和配置详情的XML文件,是用来构建(build)项目的;它包含大多数项目的默认值;例如,构建项目的【target】文件夹;例如,资源文件夹——【src/main/java】;例如测试资源文件夹——【src/test/java】等等;当执行一个任务或目标,Maven会在当前文件夹内找POM文件。然后读取POM里的信息,获取需要的配置信息,然后执行目标;
一些POM里的特殊配置是项目的依赖(Project Dependencies);这里的依赖指的是项目依赖的jar包;还有一些事插件或可执行的目标,构建配置等;其他的信息例如项目版本,描述,开发者,邮件列表等都可以被特别定义;
超级POM是Maven默认的POM,所有的POM文件们都继承了这个超级POM,除非明确定义了不继承;超级POM文件被你创建的其他POM文件们继承,目前最新的超级POM文件是3.5.4;(你可以理解为所有POM文件的基类,父类);下面是一个样例
4.0.0
central
Central Repository
https://repo.maven.apache.org/maven2
default
false
central
Central Repository
https://repo.maven.apache.org/maven2
default
false
never
${project.basedir}/target
${project.build.directory}/classes
${project.artifactId}-${project.version}
${project.build.directory}/test-classes
${project.basedir}/src/main/java
${project.basedir}/src/main/scripts
${project.basedir}/src/test/java
${project.basedir}/src/main/resources
${project.basedir}/src/test/resources
maven-antrun-plugin
1.3
maven-assembly-plugin
2.2-beta-5
maven-dependency-plugin
2.8
maven-release-plugin
2.5.3
${project.build.directory}/site
release-profile
performRelease
true
true
maven-source-plugin
attach-sources
jar-no-fork
true
maven-javadoc-plugin
attach-javadocs
jar
true
maven-deploy-plugin
true
最简单的POM文件要求有一下5个部分:
下面是一个例子
4.0.0
com.mycompany.app
my-app
1
一个POM文件会要求配置你的groupId,artifactId和版本号;这3个值可以完整的定义一个产品;以
的形式;按照上面的例子,上面项目完整的产品名是:
com.mycompany.app:my-app:1
同样的,第一节提到的,如果没有明确定义配置信息,Maven会使用默认值。其中一种默认值是打包类型(packaging type);每个Maven 项目都有一个打包类型;如果POM里没有明确定义,那么,默认的打包类型会是jar包;
此外,你可以看到,最简单的POM文件里,仓库(repositories)是没有明确配置的。如果你使用最简单的POM文件来构建项目,他会继承超级POM的仓库配置;因此,当Maven看到最简单POM文件里的依赖,他会直接去中央仓库去下载(http://repo.maven.apache.org/maven2
),这是所有POM文件的超级POM配置仓库;
POM文件里元素的会被合并如下:
超级POM文件是一个项目继承的经典例子,但是,如果你想通过特定的POM中父类元素引入你自己的父类POM文件,建议看看以下案例演示:
4.1、案例一
举例如下,让我们复用前面的产品,com.mycompany.app:my-app:1
,并且让我们引入一个其他的产品:com.mycompany.app:my-module:1
;
4.0.0
com.mycompany.app
my-module
1
让我们特别定义文件目录结构如下:
.
|-- 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文件如下:(即,我们再子类的POM文件里修改,添加父类的信息)
com.mycompany.app
my-app
1
4.0.0
com.mycompany.app
my-module
1
注意,我们添加了一个标签组节,这个组节允许我们在POM文件里特别定义产品的父类信息;我们通过定义其父类POM的【全限定产品名】(fully qualified artifact name);我们的模块就可以继承其父类POM了;
除此之外,如果我们想让我们模块的groupID或version和其父类一样,我们可以移除子类模块POM文件中的groupId或version;
com.mycompany.app
my-app
1
4.0.0
my-module
4.2、案例二
然而,上述案例一的那种情况,必须是父项目已经在我们本地仓库安装(installed)或者被特别定义了结构pom.xml
父pom.xml是一个比你当前模块的pom.xml高级的文件夹;
但是,如果父项目没有被安装或者文件夹结构是如下的例子:
.
|-- my-module
| `-- pom.xml
`-- parent
`-- pom.xml
解决方案:
添加文件夹结构地址(或任意其他目录地址),我们可以添加关联路径
原来到父组节里
com.mycompany.app
my-app
1
../parent/pom.xml
4.0.0
my-module
作为名字的建议,模块的相对路径的pom.xml是父pom.xml
项目的聚类类似于项目的继承,但是不是在模块的父pom文件,而是在父POM里;通过这样的操作,父项目可以知道他的子模块,并且,如果Mavne命令是在父项目里调用的,Maven命令可以在父模块中执行;为了做模块聚合,你必须做如下操作:
1. 修改父POMs打包的值为pom(而不是jar)
2. 特别定义父类的POM中子模块的目录
5.1、案例三
下面给定了一个原始的产品的POMs和目录结构
com.mycompany.app:my-app:1's POM
的POM
4.0.0
com.mycompany.app
my-app
1
和
com.mycompany.app:my-module:1's POM
的POM文件
4.0.0
com.mycompany.app
my-module
1
目录结构
.
|-- my-module
| `-- pom.xml
`-- pom.xml
解决方案
如果我们想将my-module
模块聚合到 my-app
模块,我们需要紧紧修改my-app
模块的POM:
4.0.0
com.mycompany.app
my-app
1
pom
my-module
在修订后的com.mycompany.app:my-app:1
模块,打包的组节和模块的组节被添加进去了;为了打包,他的值被修改为了“pom”,并且模块的组节,我们有元素:
模块的值是com.mycompany.app:my-app:1
相对 com.mycompany.app:my-module:1's POM
的相对路径;(我们特别用了模块的产品的模块目录名);
现在,无论Maven命令处理 com.mycompany.app:my-app:1
,相同的maven命令会同时在 com.mycompany.app:my-module:1
里执行;此外,一些命令(目标特别定义)的会被项目特殊处理;
5.2、案例四
但是,如果我们按照下面的来修改目录呢?
.
|-- my-module
| `-- pom.xml
`-- parent
`-- pom.xml
父类的POM会不会被模块特别定义?
解决方案:
答案?和案例3一样,通过特别定义模块的相对路径:
4.0.0
com.mycompany.app
my-app
1
pom
../my-module
即可;
如果你有好几个Maven工程,并且他们都有相似的配置,你可以通过添加父类项目和相似的配置文件来重构项目;所有你要做的就是让你的Maven工程继承其父类项目,并且配置必须与其一致;
并且,如果你有一个项目组,你要构建或者同时处理,你可以创建一个父工程,并且让父工程来定义它的子类;这样,你紧紧需要构建父项目,其他的子项目就会自动执行,不需要你操心了;
但是,同样的,你如果既有项目继承又有项目依赖;注意,你可以特定一个父项目,同时,定义这个父项目的子项目;你必须遵循下面3条规则:
1. 在父POM定义其所有的子项目POM;
2. 修改父项目的POMs的打包方式为pom
3. 特别定义父POM的目录给子项目;
6.1、案例5
给定了如下原始的POMs的产品
com.mycompany.app:my-app:1’s POM
4.0.0
com.mycompany.app
my-app
1
com.mycompany.app:my-module:1’s POM
4.0.0
com.mycompany.app
my-module
1
目录结构如下:
.
|-- my-module
| `-- pom.xml
`-- parent
`-- pom.xml
解决方案
为了两个项目都继承和聚合,你仅仅需要遵从上述3条内容;
com.mycompany.app:my-app:1’s POM
4.0.0
com.mycompany.app
my-app
1
pom
../my-module
com.mycompany.app:my-module:1’s POM
com.mycompany.app
my-app
1
../parent/pom.xml
4.0.0
my-module
注意:配置文件的继承相同的继承策略;
Maven鼓励的一个经验就是【不要重复】;然而,如果你需要使用在不同的地方多次使用相同的变量;为了帮助变量是唯一定义的,Maven允许你在POM文件里预定义自己的变量;
例如,为了得到 project.version
变量,你可以定义如下:
${project.version}
注意一个事实,变量在被继承之后处理;这意味着,如果一份父项目要使用一个变量,如果这个变量定义在子项目中,而不是父项目中,则子项目中的变量将会被最终使用;