01-基础知识

聚合项目

  1. 其pom.xml中package要声明为pom
  2. 其pom.xml中modules元素及module声明需要聚合模块的pom.xml的路径,一般用相对路径

被继承的父项目

使用parent元素声明父项目坐标,并用指明父项目pom.xml的路径,一般用相对路径,其默认值是../pom.xml,也就是Maven默认父pom在上一层目录下。

通常情况下,一个pom可以既是聚合项目,又是继承项目。

超级POM

任何一个Maven项目都隐式的继承自该POM,类似于任何一个Java类都继承自Object类。

对于Maven3,超级POM在MAVEN_HOME/lib/maven-model-builder-x.x.x.jar中的org/apache/maven/model/pom-4.0.0.xml中。

  1. 定义了依赖仓库和插件仓库
  2. 定义了项目的主输出目录,主代码输出目录、最终构件的名称格式等等
  3. 核心插件版本

反应堆

在一个多模块的Maven项目中,反应堆是指所有模块组成的一个构建结构。对于单模块的项目,反应堆久是该项目本身,但对多模块项目,反应堆就包含了各模块之间继承与依赖的关系,从而能自动计算出合理的模块构建顺序。

Maven按序读取pom,如果该pom没有依赖模块,那就会构建该模块,否则就先构建其依赖模块,如果依赖模块还依赖其他模块,则进一步构建依赖的依赖模块。

构件坐标配置

任何一个构件都必须明确定义自己的坐标,该坐标是通过一些元素定义的,它们是groupId、artifactId、version、packaging、classifier。如下:

1
2
3
4
<groupId>org.sonatype.nexus</groupId>
<artifactId>nexus-indexer</artifactId>
<version>2.0.0</version>
<packing>jar</packing>
  • groupId: 定义当前Maven项目隶属的实际项目。

推荐命名:倒写公司域名+项目名,如上标示 sonatype.org公司下的nexus项目。

  • artifactId:定义实际项目中的一个模块。

推荐命名:项目名+模块名,即使用项目名作前缀,因为一个公司会有很多项目,如果每个项目都有一个名为core的模块,再者默认情况下,构件的名称会以artifactId和version构成,此时没有前缀的话,就会有很多core-1.2.jar等,难以区分,但是引用时可通过groupId区分。
如上标示nexus项目下的indexer模块。

  • version: 版本号
  • packaging: 定义该构件的打包方式,如jar、war、pom、maven-plugin、ear等。
  • classifier: 定义构件输出一些附属构件,如javadoc和source等,不能直接定义项目的classifier。

如下groupId、artifactId、version是必须定义的,packaging是可选的(默认是jar),而classifier是不能直接定义的。

依赖配置

一个依赖声明可以包含如下元素:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<project>
<dependencies>
<dependency>
<groupId></groupId>
<artifactId></artifactId>
<version></version>
<packing></packing>

<type></type>
<scope></scope>
<optional></optional>
<exclusions>
<exclusion>
</exclusion>
</exclusions>
</dependency>

...
</dependencies>
</project>
  • type: 依赖的类型,对应项目坐标定义的packaging,默认为jar
  • scope: 依赖的范围
  • optional: 标记依赖是否可选
  • exclusions: 用来排除传递性依赖

依赖范围

Maven在构建项目时会有三种classpath,分别是编译时、测试时、运行时,依赖范围就是用来控制依赖在哪种classpath下生效的。

  1. compile: 编译依赖范围(不指定时默认)

对编译时、测试时、运行时三种classpath都有效

  1. test: 测试依赖范围

只对测试classpath有效,如Junit

  1. provided: 已提供依赖范围

对编译和测试classpath有效,但在运行时无效,如servlet-api,编译和测试时需要改依赖,运行时容器已提供,不需再重复引入。

  1. runtime: 运行时依赖范围

对测试和运行classpath有效,在编译主代码时无效,如jdbc驱动,编译时只需jdk的jdbc接口即可,只有在测试和运行时才需驱动实现。

  1. system: 系统依赖范围

此类依赖不通过maven仓库解析,必须用systemPath元素显示指定依赖文件路径,和provided依赖范围一样。

  1. import(Maven 2.0.9及以上) : 导入依赖范围

该依赖范围仅在dependencyManagement元素下才有效果,通常指向一个pom,作用是将目标pom中的dependencyManagement配置导入并合并到当前pom的dependencyManagement元素中。

参考资料