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" |
未完待续…