什么是 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
PS C:\Users\fuyon> java -version
java version "11.0.1" 2018-10-16 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.1+13-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.1+13-LTS, mixed mode)
Windows
解压
将下载好的安装包 apache-maven-3.6.1-bin.zip
解压至 C:\
(或其他路径)。
配置环境变量
打开 控制面板
> 系统和安全
> 系统
> 高级系统设置
> 环境变量
> 系统变量
- 新建一个
变量名
为M2_HOME
,变量值为C:\apache-maven-3.6.1
(即 Maven 的安装路径)。 - 选中
系统变量
中的Path
,并新增%M2_HOME%\bin\
验证
打开终端,输入 mvn --version
,输出
PS C:\Users\fuyongde> mvn --version
Apache Maven 3.5.2 (138edd61fd100ec658bfa2d307c43b76940a5d7d; 2017-10-18T15:58:13+08:00)
Maven home: C:\apache-maven-3.5.2\bin\..
Java version: 1.8.0_162, vendor: Oracle Corporation
Java home: C:\Program Files\Java\jdk1.8.0_162\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 10", version: "10.0", arch: "amd64", family: "windows"
表示安装成功
Linux & Mac OS
你都用这操作系统了,那肯定会安装吧 🤣。
使用
快速开始
Maven 提供了丰富的模板,以供我们快速创建一个工程。其命令如下:
mvn archetype:generate
-DgroupId=com.demo
-DartifactId=hello-maven
-DarchetypeArtifactId=maven-archetype-quickstart
-DinteractiveMode=false
其中各个参数的含义:
-DgroupId
:组织的唯一标识符-DartifactId
:项目的唯一标识符-DarchetypeArtifactId
:指定 ArchetypeId,常见的选项maven-archetype-quickstart
(Java project)、maven-archetype-webapp
(web project)-DinteractiveMode
:是否使用交互模式
目录结构
不同的模板创建出来的项目目录可能会有差异,常见的 Maven 目录结构如下:
├── src
│ ├── main
│ │ ├── java # 源码目录
│ │ └── resources # 资源目录
│ └── test
│ ├── java # 单元测试源码目录
│ └── resources # 单元测试资源目录
├── target # 项目编译输出的目录
├── pom.xml
Maven 生命周期
Maven 默认的生命周期包括:
validate
: 验证项目是否正确,并提供所有必要的信息compile
: 编译源码test
: 使用合适的单元测试框架测试编译的源代码,单元测试的代码并不会被打包。package
: 获取已编译的代码并将其打包为可分发的格式,例如 JAR。integration-test
: 如有必要,将程序包处理并部署到可以运行集成测试的环境中verify
: 验证打包文件是否有效并符合质量标准install
: 将项目打包安装到本地存储库中,以便在本地用作其他项目的依赖项deploy
: 将项目打包并推送到 Maven 私服或中央仓库
此外还有两个生命周期的阶段
clean
: 清除之前构建site
: 为此项目生成站点文档
POM
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
最基本的构成如下:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-project</artifactId>
<version>1.0</version>
</project>
其中
modelVersion
:Maven2 & 3
只支持 4.0.0groupId
:组织的唯一标识符artifactId
:项目的唯一标识符version
:版本号
packaging
在 pom.xml
中可以添加 <packaging>war</packaging>
来标识项目最终的打包格式,缺省值为:jar
,可选值:pom
, jar
, maven-plugin
, ejb
, war
, ear
, rar
。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<packaging>war</packaging>
...
</project>
POM Relationships(重点)
Maven 的一个强大的功能,就是它处理项目之间关系的能力,包括了:依赖项管理、继承和聚合。
依赖
依赖管理是 POM
的灵魂,大部分的项目都会依赖于其他项目来构建以及正确的运行。通过依赖管理,我们可以方便的下载、引入所需的其他依赖项。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<type>jar</type>
<scope>test</scope>
<optional>true</optional>
</dependency>
...
</dependencies>
...
</project>
groupId、artifactId
表示依赖项的坐标。由于依赖项都是由 Maven 坐标,意味着我们的项目只能依赖于同样是 Maven 管理的其他项目。但是很多时候,项目可能会依赖一些具有闭源许可的 jar
,这些 jar
并不存在于中央仓库
,有三种办法可以解决这个问题。
- 使用
install
插件在本地安装依赖项,这是最简单也是最推荐的方式。例如:
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
时使用,必须指定本地的绝对路径,且必须保证文件存在。例如:
<dependency>
<groupid>org.hamcrest</groupid>
<artifactid>hamcrest-core</artifactid>
<version>1.5</version>
<scope>system</scope>
<systempath>${basedir}/WebContent/WEB-INF/lib/hamcrest-core-1.3.jar</systempath>
</dependency>
optional
标记依赖项是否可选,缺省值为 false
。
若项目 A
依赖项目 B
,项目 B
依赖项目 C
且 optional
为 true
,此时若 项目 A
没有显式的依赖 C
,则项目 A
不依赖 C
,且打包过程中,不会将 C
打包进来。例如 fastjson
依赖了 spring-webmvc
,若使用者在开发的项目依赖了 fastjson
并且没有依赖 spring-webmvc
,则此项目是不依赖 spring-webmvc
。
排除依赖项
由于依赖的传播的特性,我们可以排除一个依赖项中我们不需要的依赖。
排除部分依赖项
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<version>2.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
</exclusion>
</exclusions>
</dependency>
...
</dependencies>
...
</project>
排除所有依赖项
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<version>3.1.0</version>
<exclusions>
<exclusion>
<groupId>*</groupId>
<artifactId>*</artifactId>
</exclusion>
</exclusions>
</dependency>
...
</dependencies>
...
</project>
继承
在继承关系中,父工程的 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
看一个列子
父工程:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-parent</artifactId>
<version>2.0</version>
<packaging>pom</packaging>
</project>
子工程
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-parent</artifactId>
<version>2.0</version>
<relativePath>../my-parent</relativePath>
</parent>
<artifactId>my-project</artifactId>
</project>
其中 relativePath
不是必需的,但如果指定了,该路径则会作为搜索父工程的首选项。
Dependency Management
在存在多个项目的情况下,在在父项目中定义 dependencyManagement
来帮住管理所有子项目的依赖项。如果在父项目中的 dependencyManagement
标签下定义了某个依赖项的信息,则在子项目中只需要填写该依赖项的 groupId
和 artifactId
即可。好处是可以避免不同的子项目,引入不同版本的依赖项。
聚合
聚合可以将不同的模块,聚合在一起进行构建。
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.codehaus.mojo</groupId>
<artifactId>my-parent</artifactId>
<version>2.0</version>
<packaging>pom</packaging>
<modules>
<module>my-project</module>
<module>another-project</module>
<module>third-project/pom-example.xml</module>
</modules>
</project>
未完待续...