Maven 手册
什么是 Maven
Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project’s build, reporting and documentation from a central piece of information.
Apache Maven 本质是一个软件项目管理和理解工具,它提供了一种项目管理的方法,涵盖了了项目管理中常见的阶段:
- Builds
- Documentation
- Reporting
- Dependencies
- SCMs
- Releases
- Distribution
安装
从官网下载安装包。
基础环境
Maven 依赖 Java
环境,所以要先确保已经正确安装 JDK
。
通过 java -version
命令来查看是否正确安装了 JDK
1 | PS C:\Users\fuyon> java -version |
Windows
解压
将下载好的安装包 apache-maven-3.6.1-bin.zip
解压至 C:\
(或其他路径)。
配置环境变量
打开 控制面板
> 系统和安全
> 系统
> 高级系统设置
> 环境变量
> 系统变量
- 新建一个
变量名
为M2_HOME
,变量值为C:\apache-maven-3.6.1
(即 Maven 的安装路径)。 - 选中
系统变量
中的Path
,并新增%M2_HOME%\bin\
验证
打开终端,输入 mvn --version
,输出
1 | PS C:\Users\fuyongde> mvn --version |
表示安装成功
Linux & Mac OS
你都用这操作系统了,那肯定会安装吧 🤣。
使用
快速开始
Maven 提供了丰富的模板,以供我们快速创建一个工程。其命令如下:
1 | mvn archetype:generate |
其中各个参数的含义:
-DgroupId
:组织的唯一标识符-DartifactId
:项目的唯一标识符-DarchetypeArtifactId
:指定 ArchetypeId,常见的选项maven-archetype-quickstart
(Java project)、maven-archetype-webapp
(web project)-DinteractiveMode
:是否使用交互模式
目录结构
不同的模板创建出来的项目目录可能会有差异,常见的 Maven 目录结构如下:
1 | ├── src |
Maven 生命周期
Maven 默认的生命周期包括:
validate
: 验证项目是否正确,并提供所有必要的信息compile
: 编译源码test
: 使用合适的单元测试框架测试编译的源代码,单元测试的代码并不会被打包。package
: 获取已编译的代码并将其打包为可分发的格式,例如 JAR。integration-test
: 如有必要,将程序包处理并部署到可以运行集成测试的环境中verify
: 验证打包文件是否有效并符合质量标准install
: 将项目打包安装到本地存储库中,以便在本地用作其他项目的依赖项deploy
: 将项目打包并推送到 Maven 私服或中央仓库
此外还有两个生命周期的阶段
clean
: 清除之前构建site
: 为此项目生成站点文档
POM
1 | POM stands for "Project Object Model". It is an XML representation of a Maven project held in a file named pom.xml. |
POM
表示“项目对象模型”,在 Maven 项目中以一个 pom.xml
文件的形式存在。
最基本的构成
一个 pom.xml
最基本的构成如下:
1 | <project xmlns="http://maven.apache.org/POM/4.0.0" |
其中
modelVersion
:Maven2 & 3
只支持 4.0.0groupId
:组织的唯一标识符artifactId
:项目的唯一标识符version
:版本号
packaging
在 pom.xml
中可以添加 <packaging>war</packaging>
来标识项目最终的打包格式,缺省值为:jar
,可选值:pom
, jar
, maven-plugin
, ejb
, war
, ear
, rar
。
1 | <project xmlns="http://maven.apache.org/POM/4.0.0" |
POM Relationships(重点)
Maven 的一个强大的功能,就是它处理项目之间关系的能力,包括了:依赖项管理、继承和聚合。
依赖
依赖管理是 POM
的灵魂,大部分的项目都会依赖于其他项目来构建以及正确的运行。通过依赖管理,我们可以方便的下载、引入所需的其他依赖项。
1 | <project xmlns="http://maven.apache.org/POM/4.0.0" |
groupId、artifactId
表示依赖项的坐标。由于依赖项都是由 Maven 坐标,意味着我们的项目只能依赖于同样是 Maven 管理的其他项目。但是很多时候,项目可能会依赖一些具有闭源许可的 jar
,这些 jar
并不存在于中央仓库
,有三种办法可以解决这个问题。
- 使用
install
插件在本地安装依赖项,这是最简单也是最推荐的方式。例如:
1 | mvn install:install-file -Dfile=non-maven-proj.jar -DgroupId=some.group -DartifactId=non-maven-proj -Dversion=1 -Dpackaging=jar |
将依赖部署到私服
将依赖的
scope
设置为system
并且定义systemPath
,强烈不推荐这种方式。
version
表示依赖的版本,关于 version
语法如下:
1.0
:若匹配到了 1.0 版本,则使用 1.0 版本[1.0]
: 强制配依赖项的 1.0 版本(,1.0]
: x <= 1.0[1.2,1.3]
: 1.2 <= x <= 1.3[1.0,2.0)
: 1.0 <= x < 2.0[1.5,)
: x >= 1.5(,1.0],[1.2,)
: x <= 1.0 or x >= 1.2,多个版本集合的情况以逗号分隔(,1.1),(1.1,)
: 排除 1.1 版本
此外,version
的不同写发也存在优先级,详情可参考官网
type
依赖项的类型,缺省值是 jar
。除此之外还有ejb-client
、test-jar
,但都不常用
scope
依赖项作用的范围以及如何限制依赖项的传递性。共五个范围值可选:
compile
:缺省值即为compile
,表示依赖项参与项目的编译、测试、运行阶段,项目打包时,也会打进去。provided
:依赖项参与项目的编译、测试阶段,与compile
不同的是不会打包进项目中,但是期望JDK
、容器
或使用者会提供该依赖项。runtime
:编译时不需要该依赖项,但是执行时需要。test
:项目不需要该依赖项,并且仅适用于单元测试的编译和执行阶段,不具有传递性。system
:使用上与provided
相同,不同之处在于该依赖不从 Maven 仓库中提取,而是从本地文件系统中提取,其会参照systemPath
的属性进行提取依赖。
systemPath
仅在 scope
为 system
时使用,必须指定本地的绝对路径,且必须保证文件存在。例如:
1 | <dependency> |
optional
标记依赖项是否可选,缺省值为 false
。
若项目 A
依赖项目 B
,项目 B
依赖项目 C
且 optional
为 true
,此时若 项目 A
没有显式的依赖 C
,则项目 A
不依赖 C
,且打包过程中,不会将 C
打包进来。例如 fastjson
依赖了 spring-webmvc
,若使用者在开发的项目依赖了 fastjson
并且没有依赖 spring-webmvc
,则此项目是不依赖 spring-webmvc
。
排除依赖项
由于依赖的传播的特性,我们可以排除一个依赖项中我们不需要的依赖。
排除部分依赖项
1 | <project xmlns="http://maven.apache.org/POM/4.0.0" |
排除所有依赖项
1 | <project xmlns="http://maven.apache.org/POM/4.0.0" |
继承
在继承关系中,父工程的 packaging
类型必须为 pom
,父工程的大多数属性会被子工程继承,包括
- groupId
- version
- description
- url
- inceptionYear
- organization
- licenses
- developers
- contributors
- mailingLists
- scm
- issueManagement
- ciManagement
- properties
- dependencyManagement
- dependencies
- repositories
- pluginRepositories
- build
- plugin executions with matching ids
- plugin configuration
- etc.
- reporting
- profiles
不会被继承的属性包括:
- artifactId
- name
- prerequisites
看一个列子
父工程:
1 | <project xmlns="http://maven.apache.org/POM/4.0.0" |
子工程
1 | <project xmlns="http://maven.apache.org/POM/4.0.0" |
其中 relativePath
不是必需的,但如果指定了,该路径则会作为搜索父工程的首选项。
Dependency Management
在存在多个项目的情况下,在在父项目中定义 dependencyManagement
来帮住管理所有子项目的依赖项。如果在父项目中的 dependencyManagement
标签下定义了某个依赖项的信息,则在子项目中只需要填写该依赖项的 groupId
和 artifactId
即可。好处是可以避免不同的子项目,引入不同版本的依赖项。
聚合
聚合可以将不同的模块,聚合在一起进行构建。
1 | <project xmlns="http://maven.apache.org/POM/4.0.0" |
未完待续…