Maven pom 详解
什么是 POM?
就像 Make 的 MakeFile、Ant 的 build.xml 一样,Maven 项目的核心是 pom.xml
。POM( Project Object Model,项目对象模型 ) 定义了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等。
快速上手
一个完整的 pom.xml
如下,放置在项目的根目录下:
4.0.0
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
POM 元素详解
The Basics
坐标( Coordinate )
概述
在 Maven 中坐标是构件的唯一标识,Maven 坐标的元素包括groupId
、artifactId
、version
、packaging
、classifier
。
其中 groupId
、artifactId
、version
是必须的.
详解
- groupId:组织标识.
- 一般为:公司网址的反写+项目名
- artifactId:项目名称.
- 一般为:项目名-模块名
- version:版本号
- 一般形式为:
0.0.1-SNAPSHOT
- 第一个
0
表示大版本号,第二个0
表示分支版本号,第三个0
表示小版本号 -
SNAPSHOT
-- 快照版本,ALPHA
-- 内侧版本,BETA
-- 公测版本,RELEASE
-- 稳定版本,GA
-- 正式发布
- 第一个
- 一般形式为:
- packaging:打包的方式.
- 如:pom, jar, maven-plugin, ejb, war, ...
- clissifier:用来帮助定义构件输出的一些附属构件。
- 详情请看: dependency 中的 classifier属性
示例
4.0.0
com.seyvoue.demo
demo-maven
1.0.0-SNAPSHOT
jar
...
依赖( dependencies )
概述
dependencies
标签是用于导入其他依赖时使用的标签. dependencies
是个依赖包, 内部含有一个或多个 dependencie
依赖.
dependencie
标签含有 groupId
artifactId
version
scope
type
optional
exclusions
等标签.
其中 groupId
artifactId
version
是必须的.
详解
groupId
artifactId
version
在坐标中已经讲解过了. 不同的是, 上面是我们自己定义, 而这里是填写别人定义好的值. 引入 jar 包的 dependencie
可在 Maven 中央库 查询.
-
scope 是 dependency 下一个控制作用域的子元素,控制该依赖包在什么情况下会被加到 classpath 中。
- scope 共 6 种,包括:
compile
、provided
、runtime
、test
、system
、import
。
- scope 共 6 种,包括:
-
optional 依赖传递的控制。
- 假设有 A, B, C 三个项目, 其依赖管辖为 B 依赖 A (B —> A), C 依赖 B (C —> B). 如果 B 的
optional
为 true. 则 C 引入 B 的时候还必须显示的引入 A 。 - 依赖传递
optional
的默认值为 false.
- 假设有 A, B, C 三个项目, 其依赖管辖为 B 依赖 A (B —> A), C 依赖 B (C —> B). 如果 B 的
-
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中谁先被声明,就使用谁。
-
聚合(modules)
通过
元素可将多个模块聚合在同一个 project 下。
4.0.0
com.seyvoue.account
account-aggregator
1.0.0-SNAPSHOT
pom
...
account-email
account-persist
继承(parent 和 dependencyManagement)
在聚合多个项目时,如果这些被聚合的项目中需要引入相同的 Jar,那么可以将这些 Jar 写入 父pom 中,各个子项目继承该pom即可。类似与 java 中的继承。
简单示例
-
父级 pom.xml
4.0.0 com.seyvoue.demo demo-maven 1.0.0-SNAPSHOT pom ...com.github.brevy shiro-spring 1.2.2 -
子集 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 :包括项目的报告输出目录配置、报告插件配置等。
属性 properties 和 &{}
简介
通过 properties
元素用户可以定义一个或多个 maven 属性,然后在 maven 的其他地方使用 ${属性名称}
的方式引用该属性,这种做法的意义在于消除重复和统一管理。比如,需要在多个地方重复声明同样的 SpringFramework 版本,现在只需要在一个地方声明就可以.
Maven 共有6种属性(根据引用的来源不同):内置属性、POM 属性、自定义属性、Settings 属性、环境变量属性等,引用方式是类似的,下面介绍其中的几种
Maven 的 properties 加载顺序:
中的配置pom.xml 中的
-
mvn -Dproperty=value
中定义的property
相同 key 的 property,以最后一个文件中的配置为最终配置。
内置属性
两个常用内置属性:
-
${basedir}
表示项目根目录 -
${version}
表示项目版本
POM 属性
用户可以使用该类属性引用 pom.xml 中对应元素的值.
如 ${project.artifactId}
就对应了
中的值。
常用属性:
-
${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
...
使用的时候直接用 ${my.group}
即可
settings 属性
与 POM 属性同理。maven settings.xml
(一般在 localUser/.m2/settings.xml
)中定义的内容,可以通过 settings
前缀进行引用。
${settings.localRepository} 表示 maven 本地仓库的路径
${settings.offline} 表示构建系统是否在离线模式下工作
Build Settings
根据 POM 4.0.0 XSD,build 元素概念性的划分为两个部分:
- BaseBuild(包含 poject build 和 profile build 的公共部分)
- poject build 包含的一些高级特性。
...
...
...
build
基础属性
示例
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/
resources
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 不被部署。
plugins
给出构建过程中所用到的插件,以及可以在这个元素下对插件进行配置。
示例
...
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 的其他配置参数
-
pluginManagement
在
中,
与
并列,两者之间的关系类似于
与
之间的关系。
中也配置
,其配置参数与
中的
完全一致。只是,
往往出现在父项目中,其中配置的
往往通用于子项目。
子项目中只要在
中以
声明该插件,该插件的具体配置参数则继承自父项目中
对该插件的配置,从而避免在子项目中进行重复配置。
reporting
中的配置作用于 Maven 的 site 阶段( 见 Maven 生命周期),用于生成报表。
中也可以配置插件
,并通过一个
的
为该插件配置参数。
注意,对于同时出现在
和
中的插件,
中对该插件的配置也能够在构建过程中生效,即该插件的配置是
和
中的配置的合并。
Environment Settings
//待完善
SCM
//待完善
distributionManagement
//待完善
profiles
//待完善
pom 完整的注释文件
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}
...
...
参考
Maven POM 详解