- Maven 的本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM)。
- POM(Project Object Model):项目对象模型。
Maven笔记
1.Maven简介
1.1 Maven是什么
Maven 的本质是一个项目管理工具,将项目开发和管理过程抽象成一个项目对象模型(POM)。
- POM(Project Object Model):项目对象模型。

- 蓝色框中的部分即为 maven。
1.2 Maven的作用
项目构建:提供标准的、跨平台的自动化项目构建方式
依赖管理:方便快捷的管理项目依赖的资源(jar包),避免资源间的版本冲突问题
统一开发结构:提供标准的、统一的项目结构

2.★Maven基础概念
2.1 仓库
仓库:用于存储资源,包含各种 jar 包。

仓库分类:
- 本地仓库:自己电脑上存储资源的仓库,连接远程仓库获取资源。
- 远程仓库:非本机电脑上的仓库,为本地仓库提供资源。
- 中央仓库:Maven 团队维护,存储所用资源的仓库。
- 私服:部门/公司范围内存储资源的仓库,从中央仓库获取资源。
私服的作用:
- 保存具有版权的资源,包含购买或自主研发的 jar
- 中央仓库中的 jar 都是开源的,不能存储具有版权的资源
- 一定范围内共享资源,仅对内部开放,不对外共享,访问速度快
- 保存具有版权的资源,包含购买或自主研发的 jar
2.2 坐标
什么是坐标?
Maven 中的坐标用于描述仓库中资源的位置,即用来定位资源。
Maven 坐标主要组成:
groupld
:定义当前 Maven 项目隶属组织名称(例如:org.mybatis)。artifactld
:定义当前 Maven 项目名称(通常是模块名称,例如 CRM、SMS)。version
:定义当前项目版本号。
例如下面是指定了具体某个版本的
log4j
jar 包的坐标:1
2
3
4
5
6<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>Maven坐标的作用
使用唯一标识,唯一性定位资源位置,通过该标识可以将资源的识别与下载工作交由机器完成。
2.3 仓库配置
maven 可以对本地仓库和远程仓库进行配置(在
apache-maven-3.9.6\conf\settings.xml
中进行修改):本地仓库:定义了下载的 jar 包存放的位置,默认存储在
${user.home}/.m2/repository
。这里修改为D:\maven\repository
。1
2
3
4
5
6
7<!-- localRepository
| The path to the local repository maven will use to store artifacts.
|
| Default: ${user.home}/.m2/repository
<localRepository>/path/to/local/repo</localRepository>
-->
<localRepository>D:\maven\repository</localRepository>远程仓库:定义了从哪下载 jar 包,默认为
https://repo.maven.apache.org/maven2
,是国外的网址,访问速度较慢。这里修改为阿里镜像仓库https://maven.aliyun.com/repository/central
。1
2
3
4
5
6
7
8
9
10
11
12
13<mirrors>
<!-- 配置具体的仓库的下载镜像 -->
<mirror>
<!-- 此镜像的唯一标识符,用来区分不同的mirror元素 -->
<id>nexus-aliyun</id>
<!-- 对哪种仓库进行镜像,简单说就是替代哪个仓库,这里是替代中央仓库 -->
<mirrorOf>central</mirrorOf>
<!-- 镜像名称 -->
<name>Nexus aliyun</name>
<!-- 镜像的具体地址 -->
<url>https://maven.aliyun.com/repository/central</url>
</mirror>
</mirrors>
全局 setting 与用户 setting 区别:
- 全局 setting 定义了当前计算机中 Maven 的公共配置。
- 用户 setting 定义了当前用户的配置。
3.★第一个Maven项目
首先新建一个项目
maven_project
,构建系统选择maven
:
- 组ID 即为
groupId
- 工件ID 即为
artifactId
- 组ID 即为
然后在设置中设置我们自己选定的 maven 版本,以及我们之前修改好的配置:

此时项目结构如下,可以根据需要在
test
目录下添加resource
目录:
main
存储项目开发代码,test
存储项目测试代码。main
中的java
存储项目开发源代码,test
中的java
存储项目开发测试源代码。main
中的resources
存储项目开发的资源配置文件,test
中的resources
存储项目测试的资源配置文件。
接着可以修改
pom.xml
文件,该文件与src
目录在同一级结构。例如在
pom.xml
文件中添加依赖:1
2
3
4
5
6
7<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
</dependency>
</dependencies>可以用下图右上角的刷新按钮进行刷新,如果当前本地仓库中没有所依赖的 jar 包,就会去远程仓库进行下载:

- 另外注意到,依赖项和我们当前的项目的坐标结构是一样的。
- 因为我们可以根据坐标去下载我们要依赖的资源,而我们自己开发的项目,本身也可以作为他人依赖的资源。如果别人想要使用我们开发的项目作为他依赖的资源,那他将我们项目的信息添加到
dependency
标签中即可。
- 因为我们可以根据坐标去下载我们要依赖的资源,而我们自己开发的项目,本身也可以作为他人依赖的资源。如果别人想要使用我们开发的项目作为他依赖的资源,那他将我们项目的信息添加到
- 另外注意到,依赖项和我们当前的项目的坐标结构是一样的。
也可以在
pom.xml
文件中添加插件,例如添加tomcat
插件:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16<!-- 构建 -->
<build>
<!-- 设置插件 -->
<plugins>
<!-- 具体的插件配置 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<port>80</port>
<path>/</path>
</configuration>
</plugin>
</plugins>
</build>
然后就可以进行项目的开发了,一个简单的项目开发如下:

项目开发完以后,就可以开始构建项目,可以用下图右边的按键:
也可以在运行配置中设置:

4.★依赖管理
4.1 依赖配置
依赖指当前项目运行所需要的 jar 包,一个项目可以设置多个依赖。
格式:
1
2
3
4
5
6
7
8
9
10
11
12<!-- 设置当前项目所依赖的所有jar -->
<dependencies>
<!-- 设置具体的依赖 -->
<dependency>
<!-- 依赖所属组织id -->
<groupId>junit</groupId>
<!-- 依赖所属项目id -->
<artifactId>junit</artifactId>
<!-- 依赖版本号 -->
<version>4.12</version>
</dependency>
</dependencies>
4.2 依赖传递
依赖具有传递性
- 直接依赖:在当前项目中通过依赖配置建立的依赖关系
- 间接依赖:当前项目所依赖的资源如果依赖其他资源,则该项目间接依赖其他资源,该项目也可以直接使用这些其他资源。

依赖传递中存在冲突问题,例如
project01
直接依赖project02
,而:project01
直接依赖了log4j 1.2.13
,project02
直接依赖了log4j 1.2.14
那
project01
使用的到底是log4j 1.2.13
还是log4j 1.2.14
?- 使用的是
log4j 1.2.13
。
- 使用的是
对于依赖传递的冲突问题,有以下几个优先原则:
路径优先:当依赖中出现相同的资源时,层级越深,优先级越低,层级越浅,优先级越高。
- 优先级:1度 > 2度 > 3度 > 4度……

声明优先:当资源在相同层级被依赖时,配置顺序靠前的覆盖配置顺序靠后的。
特殊优先:当同级配置了相同资源的不同版本,后配置的覆盖先配置的。
4.3 可选依赖
可选依赖指对外隐藏当前所依赖的资源 –> 不透明。
- 例如如果在
project02
中隐藏了log4j 1.2.14
,那在project01
中就看不到project02
依赖了log4j 1.2.14
,那project01
肯定依赖的就是log4j 1.2.13
了。
1
2
3
4
5
6
7<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!-- 设置optional为true表示对外隐藏 -->
<optional>true</optional>
</dependency>- 例如如果在
4.4 排除依赖
排除依赖指主动断开依赖的资源,被排除的资源无需指定版本。
可选依赖和排除依赖的区别:
- 首先要明确,可选依赖和排除依赖都是从当前开发的项目的视角上来看的。
- 可选依赖表示你的这个项目不希望让别人知道你依赖了哪些资源,当别人使用你的资源的时候,是看不见你依赖了哪些资源的。
- 排除依赖表示你的这个项目在依赖别人的资源的时候,不想要间接依赖别人的资源依赖的其他那些资源。
1
2
3
4
5
6
7
8
9
10
11
12
13<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!-- 要排除的那些间接依赖 -->
<exclusions>
<!-- 具体的要排除的间接依赖 -->
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>- 首先要明确,可选依赖和排除依赖都是从当前开发的项目的视角上来看的。
4.5 依赖范围
依赖的 jar 默认情况可以在任何地方使用,可以通过
scope
标签设定其作用范围。- 作用范围
- 主程序范围有效(
main
文件夹范围内) - 测试程序范围有效(
test
文件夹范围内) - 是否参与打包(
package
指令范围内)
- 主程序范围有效(

- 作用范围
5.生命周期与插件
5.1 项目构建生命周期
Maven 构建生命周期描述的是一次构建过程经历了多少个事件。

Maven 对项目构建的生命周期划分为 3 套:
clean
:清理工作default
:核心工作,例如编译,测试,打包,部署等site
:产生报告,发布站点等
clean生命周期

default生命周期

- 注:执行其中一条时,会将其上面的全部执行一遍。
- 例如执行
test
前,会将test
上面的命令先全部执行一遍。
- 例如执行
site生命周期

5.2 插件
上面生命周期中的这些事情是谁做的呢?
由 maven 插件来实现。
插件与生命周期内的阶段绑定,在执行到对应生命周期时执行对应的插件功能。
默认 maven 在各个生命周期上绑定有预设的功能。
- 如果你觉得 maven 预设的功能还不够,也可以通过插件自定义其他功能。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<build>
<plugins>
<!-- 下面这是一个对代码打包的插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<goals>
<!-- 指定对测试源码进行打包 -->
<goal>test-jar</goal>
</goals>
<!-- 指定你的这个插件在什么时候执行 -->
<phase>generate-test-resources</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
简单来说,项目构建生命周期类似于人在人生的不同阶段,插件类似于在不同的人生阶段做了哪些事情。