- 前言
- 什么是 POM
- Quick Overview
- POM 常用元素
- pom.xml 完整注释
- 参考
0 前言
什么是 POM?
就像 Make 的 MakeFile、Ant 的 build.xml 一样,Maven 项目的核心是 pom.xml
。POM( Project Object Model,项目对象模型 ) 定义了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等。
Quick Overview
一个完整的 pom.xml
如下,放置在项目的根目录下:
4.0.0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
tips:这里的 pom.xml
的 modelVersion
为 4.0.
1 POM 常用元素
1.1 The Basics
1.1.1 Maven 坐标( Coordinate )
在 Maven 中坐标是构件的唯一标识,Maven 坐标的元素包括 groupId
、artifactId
、version
、packaging
、classifier
。上述5个元素中,groupId
、artifactId
、version
是必须定义的,packaging
是可选的 ( 默认为 jar )。
- groupId:组织标识,一般为:公司网址的反写+项目名
- artifactId:项目名称,一般为:项目名-模块名
- version:版本号
- packaging:打包的方式,如:pom, jar, maven-plugin, ejb, war, ...
- clissifier:用来帮助定义构件输出的一些附属构件。可参考此文
另外,关于 版本号 ,形式为0.0.1-SNAPSHOT
:
- 第一个
0
表示大版本号,第二个0
表示分支版本号,第三个0
表示小版本号 -
SNAPSHOT
-- 快照版本,ALPHA
-- 内侧版本,BETA
-- 公测版本,RELEASE
-- 稳定版本,GA
-- 正式发布
在我们开发自己的 maven 项目的时候,需要为其定义适当的坐标,如:
4.0.0
com.seyvoue.demo
demo-maven
1.0.0-SNAPSHOT
jar
...
1.1.2 依赖: ...
比如,我的项目 project-demo1
需要添加 junit
依赖:
junit
junit
4.0
jar
test
true
...
dependencies
元素,包括以下子元素:
- groupId, artifactId, version
这三个是必须的,以下的那些子元素根据实际情况添加。
- scope
scope 元素为 maven dependency 下一个控制作用域的子元素,控制该依赖包在什么情况下会被加到 classpath 中。共 6 种 scope,包括:
compile
、provided
、runtime
、test
、system
、import
。
( 具体可参考@POM Dependency Scope )
- type
对于于
,即指定依赖包的后缀,默认为
... jar
- optional
如果当前仙姑是 projectA,projectA 需要依赖 projectB,而 projectB 的 optional 为 true,表示依赖可选,那么之后所有声明依赖 projectA 的项目如果也依赖 projectB,就必须手动声明。
比如,projectC 依赖 projectA 和 projectB,如果 projectC只声明了对 projectA 的依赖,那么 projectB 不会自动加入依赖,projectA 必须手动加入对 projectB 的依赖。
也就是说依赖传递被打断了。
- exclusions
依赖传递:如果我们的项目引用了一个 Jar 包,而该 Jar 包又引用了其他 Jar 包,那么在默认情况下项目编译时,Maven 会把直接引用和间接引用的 Jar 包都下载到本地。
排除依赖:如果我们只想下载直接引用的 Jar包,
那么需要在 pom.xml 中做如下配置:(将需要排除的 Jar 包的坐标写在中)
...
ch.qos.logback
logback-classic
...
依赖冲突:若项目中多个 Jar 同时引用了相同的 Jar 时,会产生依赖冲突,但 Maven 采用了两种避免冲突的策略,因此在 Maven 中是不存在依赖冲突的。
- 短路优先
本项目——>A.jar——>B.jar——>X.jar
本项目——>C.jar——>X.jar
若本项目引用了 A.jar,A.jar 又引用了 B.jar,B.jar 又引用了 X.jar,并且 C.jar 也引用了X.jar。
在此时,Maven 只会引用引用路径最短的Jar。- 声明优先
若引用路径长度相同时,在pom.xml中谁先被声明,就使用谁。
1.1.3 聚合: ...
通过
元素可将多个模块聚合在同一个 project 下。
...
4.0.0
com.seyvoue.account
account-aggregator
1.0.0-SNAPSHOT
pom
...
account-email
account-persist
1.1.4 继承: ... 和 ...
在聚合多个项目时,如果这些被聚合的项目中需要引入相同的 Jar,那么可以将这些 Jar 写入 父pom 中,各个子项目继承该pom即可。类似与 java 中的继承。
(具体可参考@Maven的聚合与继承)
如何实现继承? 示例如下:
- 父 pom.xml:
必须配置为
... pom
- 将需要继承的 Jar 包的坐标放入
内即可
...
4.0.0 com.seyvoue.demo demo-maven 1.0.0-SNAPSHOT pom ...4.0.2.RELEASE 4.7 ... ... ... com.github.brevy shiro-spring 1.2.2
- 子 pom.xml:
在
标签内添加 父pom.xml 的坐标
...
4.0.0 ...com.seyvoue.demo demo-maven 1.0.0-SNAPSHOT ... ... ... com.github.brevy shiro-spring
- Maven 可继承的 POM 元素:
groupId :项目组 ID ,项目坐标的核心元素;
version :项目版本,项目坐标的核心元素;
description :项目的描述信息;
organization :项目的组织信息;
inceptionYear :项目的创始年份;
url :项目的 url 地址
develoers :项目的开发者信息;
contributors :项目的贡献者信息;
distributionManagerment :项目的部署信息;
issueManagement :缺陷跟踪系统信息;
ciManagement :项目的持续继承信息;
scm :项目的版本控制信息;
mailingListserv :项目的邮件列表信息;
properties :自定义的 Maven 属性;
dependencies :项目的依赖配置;
dependencyManagement :醒目的依赖管理配置;
repositories :项目的仓库配置;
build :包括项目的源码目录配置、输出目录配置、插件配置、插件管理配置等;
reporting :包括项目的报告输出目录配置、报告插件配置等。
1.1.5 属性:... 和 &{}
Maven 的 properties 加载顺序:
中的配置 - pom.xml 中的
- mvn -Dproperty=value 中定义的 property
相同 key 的 property,以最后一个文件中的配置为最终配置。
...
1.7
1.7
UTF-8
UTF-8
...
通过 properties
元素用户可以定义一个或多个 maven 属性,然后在 maven 的其他地方使用 ${属性名称}
的方式引用该属性,这种做法的意义在于消除重复和统一管理。比如,需要在多个地方重复声明同样的 SpringFramework 版本,现在只需要在一个地方声明就可以。Maven 共有6种属性(根据引用的来源不同):内置属性、POM 属性、自定义属性、Settings 属性、环境变量属性等,引用方式是类似的,下面介绍其中的集中
- 内置属性
两个常用内置属性:
${basedir}
表示项目根目录${version}
表示项目版本
- POM 属性
用户可以使用该类属性引用 pom.xml 中对应元素的值,如
${project.artifactId}
就对应了中的值。常用的 POM 属性包括:
${project.build.sourceDirectory}
表示项目的主源码目录,默认为src/main/java
${project.build.testDirectory}
表示项目的测试源码目录,默认为src/test/java
${project.build.directory}
表示项目项目构建输出目录,默认为/target
${project.outputDirectory}
表示项目主代码编译输出目录,默认为/target/classes
${project.build.filename}
表示项目打包输出文件的名称,默认为${project.artifactId}-${project.version}
- 自定义属性
用户可以在 pom.xml 的
元素下定义自己的 Maven 属性。如:
... ... hello
- settings 属性
与 POM 属性同理。maven settings.xml 中定义的内容,可以通过
settings
前缀进行引用。${settings.localRepository} 表示 maven 本地仓库的路径 ${settings.offline} 表示构建系统是否在离线模式下工作
1.2 Build Settings
根据 POM 4.0.0 XSD,build 元素概念性的划分为两个部分:BaseBuild(包含 poject build 和 profile build 的公共部分,见下)和 poject build 包含的一些高级特性。
...
...
...
1.2.1 ...
1.2.1.1 The BaseBuild Element Set
Basic Elements
install
${basedir}/target
${artifactId}-${version}
filters/filter1.properties
...
- defaultGoal:执行build任务时,如果没有指定目标,将使用的默认值,如:在命令行中执行mvn,则相当于执行mvn install;
- directory:build目标文件的存放目录,默认在
${basedir}/target目录
- finalName:build目标文件的文件名,默认情况下为
${artifactId}-${version}
- filter:定义*.properties文件,包含一个properties列表,该列表会应用的支持filter的resources中。也就是说,定义在filter的文件中的"name=value"值对会在build时代替
${name}
值应用到 resources 中。Maven的默认filter文件夹是${basedir}/src/main/filters/
...
Maven 属性默认只有在 pom.xml 中才会被解析,对于放在
src/main/resources/
目录下的文件,maven 是需要通过maven-resources-plugin
插件帮忙处理的,它默认的行为是将项目资源文件复制到代码编译输出目录中,不过只要通过一些简单的 POM 配置,该插件就能解析资源文件中的 Maven 属性,即开启资源过滤。
resources(通常)不是代码,他们不被编译,但是被绑定在你的项目或者用于其它什么原因,例如代码生成。
... META-INF/plexus false ${basedir}/src/main/plexus configuration.xml **/*.properties ... ...
- resources:一个resource元素的列表,每一个都描述与项目关联的文件是什么和在哪里;
- targetPath:指定build后的resource存放的文件夹。该路径默认是basedir。通常被打包在JAR中的resources的目标路径为META-INF;
- filtering:true/false,表示为这个resource,filter是否激活。
- directory:定义resource所在的文件夹,默认为
${basedir}/src/main/resources
- includes:指定作为resource的文件的匹配模式,用
*
作为通配符;- excludes:指定哪些文件被忽略,如果一个文件同时符合
includes
和excludes
,则excludes
生效;- testResources:定义和 resource 类似,但只在
test
时使用,默认的test resource
文件夹路径是${basedir}/src/test/resources
,test resource
不被部署。
...
给出构建过程中所用到的插件,以及可以在这个元素下对插件进行配置。
... org.apache.maven.plugins maven-jar-plugin 2.6 false true test ... echodir run verify false Build Dir: ${project.build.directory}
- extensions:是否加载该插件的扩展,默认false
- inherited:该插件的 configuration 中的配置是否可以被(继承该POM的其他Maven项目)继承,默认true
- configuration:该插件所需要的特殊配置,在父子项目之间可以覆盖或合并
- dependencies:该插件所特有的依赖类库
- executions:plugin 可以有多个目标,每一个目标都可以有一个分开的配置,甚至可以绑定一个 plugin 的目标到一个不同的阶段。executions 配置一个 plugin 的目标的 execution。一个 execution 有如下设置:
- id,唯一标识
- goals,要执行的插件的 goal(可以有多个),如
run - phase,目标执行的阶段,具体值看Maven的生命周期列表
- inherited,该 execution 是否可被子项目继承
- configuration,该 execution 的其他配置参数
...
在
中,
与
并列,两者之间的关系类似于
与
之间的关系。
中也配置
,其配置参数与
中的
完全一致。只是,
往往出现在父项目中,其中配置的
往往通用于子项目。子项目中只要在
中以
声明该插件,该插件的具体配置参数则继承自父项目中
对该插件的配置,从而避免在子项目中进行重复配置。
1.2.2 ...
中的配置作用于 Maven 的 site 阶段( 见 Maven 生命周期),用于生成报表。 中也可以配置插件 ,并通过一个 的 为该插件配置参数。注意,对于同时出现在 和 中的插件, 中对该插件的配置也能够在构建过程中生效,即该插件的配置是 和 中的配置的合并。
1.3 Environment Settings
...
Maven中为我们集成了软件配置管理的(SCM:Software Configuration Management)功能,他可以支持我们常用SVN、CVS等,共支持18个命令:
scm:branch - branch the project(创建项目的分支) scm:validate - validate the scm information in the pom(校验SCM的配置信息) scm:add - command to add file(增加一个文件) scm:unedit - command to stop editing the working copy(停止编辑当前COPY) scm:export - command to get a fresh exported copy(拉一个全新的分支) scm:bootstrap - command to checkout and build a project(checkout并编译工程) scm:changelog - command to show the source code revisions(显示源码版本) scm:list - command for get the list of project files(列出工程的文件) scm:checkin - command for commiting changes(提交变更) scm:checkout - command for getting the source code(获取源码) scm:status - command for showing the scm status of the working copy(获取本地项目的状态) scm:update - command for updating the working copy with the latest changes(从服务器获取最新的版本) scm:diff - command for showing the difference of the working copy with the remote one(比较本地与远程服务器的差异) scm:update-subprojects - command for updating all projects in a multi project build(更新子项目) scm:edit - command for starting edit on the working copy(编辑) scm:tag - command for tagging a certain revision(打标签)
tips:而其中的 mvn scm:checkin
, mvn scm:update
是其中比较常用的命令。
比如,对 git
的配置如下:
... scm:svn:http://svn.baidu.com/banseon/maven/banseon/banseon-maven2-trunk(dao-trunk) scm:svn:http://svn.baidu.com/banseon/maven/banseon/dao-trunk http://svn.baidu.com/banseon ... org.apache.maven.plugins maven-release-plugin 2.5.3 ${git.conn} ${git.conn} ${git.username} ${git.password}
...
maven 中的仓库分为两种,snapshot 快照仓库和 release 发布仓库。snapshot 快照仓库用于保存开发过程中的不稳定版本,release 正式仓库则是用来保存稳定的发行版本。定义一个组件/模块为快照版本,只需要在 pom 文件中在该模块的版本号后加上-SNAPSHOT即可(注意这里必须是大写),在distributionManagement段中配置的是snapshot快照库和release发布库的地>址。
${distribution.releases.id}
${distribution.releases.url}
${distribution.snapshots.id}
${distribution.snapshots.url}
...
不同环境的构建很可能是不同的,典型的情况就是数据库的配置。要想使得一个构建不做任何修改就能在任何环境下运行,往往是不可能的,为了能让构建在各个环境下方便地移植,Maven 引入了 profile 的概念,profile 能够在构建的时候选择性的激活 pom.xml 中的元素。用户可以使用很多方式激活 profile,以实现构建在不同环境下的移植。
... test ... ... ... ... ... ... ... ... ...
2. pom.xml 完整注释
4.0.0
com.seyvoue.demo
demo-maven
1.0.0-SNAPSHOT
jar
project-demo
http://demo.seyvoue.com
A demo of maven project to study maven.
...
org.apache.maven
maven-artifact
3.8.1
jar
test
spring-core
org.springframework
true
...
account-email
account-persist
...
scm:svn:http://svn.baidu.com/banseon/maven/banseon/banseon-maven2-trunk(dao-trunk)
scm:svn:http://svn.baidu.com/banseon/maven/banseon/dao-trunk
http://svn.baidu.com/banseon
banseon-maven2
banseon maven2
file://${basedir}/target/deploy
banseon-maven2
Banseon-maven2 Snapshot Repository
scp://svn.baidu.com/banseon:/usr/local/maven-snapshot
banseon-site
business api website
scp://svn.baidu.com/banseon:/var/www/localhost/banseon-web
install
${basedir}/target
${artifactId}-${version}
filters/filter1.properties
org.apache.maven.plugins
maven-release-plugin
2.5.3
${git.conn}
${git.conn}
${git.username}
${git.password}
...
...
参考
- POM Reference -- Apache Maven Project
- pom.xml 详解 -- adeyi
- Maven实战 -- 许晓斌
- dependency 中的 classifier属性
- 利用maven的filter和profile实现不同环境使用不同的配制
- 使用 maven profile
- Maven多环境配置实战 filter
- Maven Dependency Scope
- Maven基本命令 仓库 坐标 依赖 聚合 继承 pom.xml详解
- Maven pom.xml 配置详解