Maven
一、是什么
Maven是apache下的一个开源项目,是一款用于管理和构建java项目的工具
它基于项目对象模型(POM)的概念,通过一小段描述信息来管理项目的构建。
它包含一个项目对象模型(POM)、一个依赖管理模型(Dependency)、一个构建生命周期(Build lifecyle)和一组用于构建生命周期的插件。
二、干什么
1.方便的依赖管理
官方介绍:
方便快捷的管理项目依赖的资源(jar包),避免版本的冲突问题。
传统方式,总结一下就是两个字:繁琐
需要自己下载相关jar包,然后手动导入jar包,并且还得注意jar包之间的版本配套情况
假设后期需要升级某个jar包的版本,不仅需要升级这个jar包,这个jar包所依赖的其他jar包都需要升级
使用Maven:
创建Maven项目,不需要再导入jar包,只需要在pom.xml文件中引入相关依赖,Maven会自动联网下载该依赖,并同时下载这个jar包所依赖的其他jar包,便于项目的一个升级。
2.统一的项目结构
官方介绍:
提供标准、统一的项目结构
原来的弊端:
使用不同的开发工具创建出来的java项目结构是不同的,也就是说eclipse创建的java项目无法直接导入到IDEA中去,IDEA创建的java项目也无法直接导入到eclipse中去。
使用Maven:
只要使用Maven这一工具,生成出来的项目结构都是统一的。
3.标准的项目构建流程
官方介绍:
标准跨平台(Linux、Windows、MacOS)的自动化项目构建方式
Maven提供了一套标准的构建流程。我们可以直接基于Maven提供的指令,快速完成项目的清理、编译、测试、打包、发布等操作,结果放入target文件夹下。
三、怎么用
1. Maven坐标
什么是坐标?
资源的唯一标识,通过该坐标可以唯一定义资源位置
使用坐标定义项目或引入项目中所需的依赖
Maven坐标主要组成
groupId:定义当前Maven项目隶属的组织名称(通常是域名反写)
artifactId:定义当前Maven项目名称(通常是模块名称)
version:定义当前项目版本号
//定义项目
<groupId>com.demo</groupId>
<artifactId>maven-project01</artifactId>
<version>1.0-SNAPSHOT</version>
//引入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
2.依赖管理
2.1 依赖配置
依赖:指当前项目运行所需要的jar包,一个项目可以引入多个依赖
配置:
- 在pom.xml文件中编写dependencies标签
- 在dependencies标签中使用dependency引入坐标
- 定义坐标的groupId、artifactId、version
- 点击刷新按钮,引入最新加入的坐标
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
注意事项:
如果引入的依赖,在本地仓库不存在,将会连接远程仓库/中央仓库,然后下载依赖。(这个过程会比较耗时,耐心等待)
如果不知道依赖的坐标信息,可以到https://mvnrepository.com/ 中搜索。
2.2 依赖传递
依赖具有传递性
直接依赖:在当前项目中通过依赖配置建立的依赖关系
间接依赖:被依赖的资源如果依赖其他资源,当前项目间接依赖其他资源
如果不想间接依赖其他资源,可以使用exclusion排除依赖
换个问法:如何解决依赖传递引起的版本冲突。
排除依赖:指主动断开依赖的资源,被排除的资源无需指定版本
2.3 依赖范围
依赖的jar包,默认情况下,可以在任何地方使用。可以通过scope设置其作用范围。
作用范围:
主程序范围有效(main文件夹范围内)
测试程序范围有效(test文件夹范围内)
是否参加打包运行。(package指令范围内)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
2.4 生命周期
Maven生命周期就是为了对所有的maven项目构建过程进行抽象和统一。
Maven中有3套相互独立的生命周期:
clean:清理工作
default:核心工作,如:编译、测试、打包、安装、部署等
site:生成报告、发布站点等
每套生命周期包含一些阶段(phase),阶段是有顺序的,后面的阶段依赖于前面的阶段。
clean:移除上一次构建生成的文件
compile:编译项目源代码
test:使用合适的单元测试框架进行测试
package:将编译后的文件进行打包,如:jar、war等
install:安装项目到本地仓库
deploy:拷贝最终的工程包到远程仓库中,以共享给其他的开发人员和工程
2.5 依赖原则
当依赖所层级不一样时:
最短路径优先原则(依赖传递的路径越短越优先)
当依赖层级一样时:
最先定义优先原则(路径长度一样,则先声明的优先)
特殊的最短路径优先原则:
直接依赖优先原则
3.解析机制
3.1 依赖解析机制
- 当依赖的范围是 system 的时候,Maven 直接从本地文件系统中解析构件。
- 根据依赖坐标计算仓库路径,尝试直接从本地仓库寻找构件,如果发现对应的构件,就解析成功。 如果在本地仓库不存在相应的构件,就遍历所有的远程仓库,发现后,下载并解析使用。
- 如果依赖的版本是 RELEASE 或 LATEST,就基于更新策略读取所有远程仓库的元数据文件 (groupId/artifactId/maven-metadata.xml),将其与本地仓库的元数据合并后,计算出 RELEASE 或者 LATEST 真实的值,然后基于该值检查本地仓库,或者从远程仓库下载。
- 如果依赖的版本是 SNAPSHOT,就基于更新策略读取所有远程仓库的元数据文件,将它与本地仓库对应的元数据合并,得到最新快照版本的值,然后根据该值检查本地仓库,或从远程仓库下载。如果最后解析得到的构件版本包含有时间戳,先将该文件下载下来,再将文件名中时间戳信息删除,剩下 SNAPSHOT 并使用(以非时间戳的形式使用)。
关于RELEASE 、LATEST和SNAPSHOT
LATEST:某个特定构建最新的发布版(RELEASE)或快照版(SNAPSHOT)
RELEASE:仓库中最后一个非快照版本
SNAPSHOT:特定时间的一个快照版本,maven的一个特殊版本号,maven在处理时,会把SNAPSHOT字符自动替换成时间。
3.2 插件解析机制
与依赖的构件一样,插件也是基于坐标保存在Maven仓库中。在用到插件的时候会先从本地仓库查 找插件,如果本地仓库没有则从远程仓库查找插件并下载到本地仓库。与普通的依赖构件不同的 是,Maven会区别对待普通依赖的远程仓库与插件的远程仓库。前面提到的配置远程仓库只会对普 通的依赖有效果。当Maven需要的插件在本地仓库不存在时是不会去我们以前配置的远程仓库查找 插件的,而是需要有专门的插件远程仓库。