一、什么是Maven?
Maven是Apache软件基金会组织维护的一款专门为Java项目提供构建和依赖管理支持的工具。
1.1 构建
构建过程包含的主要环节如下:
- 清理:删除上一次构建的结果,为下一次构建做好准备
- 编译:Java源程序编译成*.class字节码文件
- 测试:运行提前准备好的测试程序
- 报告:针对刚才测试的结果生成一个全面的信息
- 打包:Java工程打jar包;Web工程打war包
- 安装:把一个Maven工程安装到Maven仓库
- 部署:将准备好的jar包或war包部署到服务器上运行
1.2 依赖
如果A工程里面用到了B工程的类、接口、配置文件等等的资源,就可以说A依赖B。
依赖管理中主要解决的问题:
- jar包的下载:使用Maven之后,jar包会从规范的远程仓库下载到本地
- jar包之间的依赖:通过依赖的传递性自动完成
- jar包之间的冲突:通过对依赖的配置进行调整,让某些jar包不会被导入
二、Maven的核心概念
2.1 坐标
使用三个向量在Maven的仓库中唯一的定位到一个jar包。
- groupId:公司或组织的id
- artifactId:一个项目或者项目中的一个模块的id
- version:版本号。根据自己的需要设定,SNAPSHOT表示快照版本,正在迭代过程中,不稳定的版本;RELEASE表示正式版本。
2.2 POM
POM:Project Object Model,项目对象模型。
POM表示将工程抽象为一个模型,再用程序中的对象来描述这个模型。就可以用程序来管理项目了。在开发过程中,最基本的做法就是将现实生活中的事物抽象为模型,然后封装模型相关的数据作为一个对象,就可以在程序中计算与现实事物相关的数据。
POM理念集中体现在Maven工程根目录下pom.xml这个配置文件中。所以pom.xml配置文件就是Maven工程的核心配置文件。
2.3 Maven的常用命令
2.3.1 清除操作
mvn clean
删除target目录
2.3.2 编译操作
- 主程序编译:
mvn compile
- 测试程序编译:
mvn test-compile
- 主体程序编译结果存放的目录:
target/classes
- 测试程序编译结果存放的目录:
target/test-classes
2.3.3 测试操作
mvn test
测试的报告会存放在target/surefire-reports目录下
2.3.4 打包操作
mvn package
打包的结果会存放在target目录下
2.3.5 安装操作
mvn install
安装的效果就是将本地构建过程中生成的jar包存入Maven本地仓库。这个jar包在Maven仓库中的路径是根据它的坐标生成的。
安装操作还会将pom.xml文件转换为XXX.pom文件一起存入本地仓库。
2.4 依赖的范围
标签的位置:dependencies/dependency/scope
标签的可选值:compile/test/provided
2.4.1 compile和test对比
main目录(空间) | test目录(空间) | 开发过程(时间) | 部署到服务器(时间) | |
compile | 有效 | 有效 | 有效 | 有效 |
test | 无效 | 有效 | 有效 | 无效 |
2.4.2 compile和provided对比
main目录(空间) | test目录(空间) | 开发过程(时间) | 部署到服务器(时间) | |
compile | 有效 | 有效 | 有效 | 有效 |
provided | 有效 | 有效 | 有效 | 无效 |
2.4.3 结论
- compile:在项目实际运行时真正要用到的jar包都是以compile范围进行依赖的。
- test:测试过程中使用的jar包,以test范围依赖。
- provided:在开发过程中需要用到的“服务器上的jar包”通常以provided范围依赖。
2.5 依赖的传递性
在A依赖B,B依赖C的前提下,C是否能够传递到A,取决于B依赖C时使用的依赖范围。
- B依赖C时使用compile范围:可以传递
- B依赖C时使用test或provided范围:不能传递,所以需要这样的jar包时,就必须在需要的地方明确配置依赖才可以。
2.6 依赖的排除
当A依赖B,B依赖C而且C可以传递到A的时候,但是A不想要C,需要在A里面把C排除掉。这种情况都是为了避免jar包之间的冲突。
配置依赖的排除就是阻止某些jar包的传递。因为这样的jar包传递过来会和其他jar包冲突。
配置方式
<dependency>
<groupId>com.atguigu.maven</groupId>
<artifactId>pro01-maven-java</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
<!-- 使用excludes标签配置依赖的排除 -->
<exclusions>
<!-- 在exclude标签中配置一个具体的排除 -->
<exclusion>
<!-- 指定要排除的依赖的坐标(不需要写version) -->
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
2.7 继承
Maven工程之间,A工程(子工程)继承B工程(父工程)。本质上就是A工程的pom.xml中的配置继承了B工程中pom.xml的配置。
在父工程中统一管理项目中的依赖信息,具体来说是管理依赖信息的版本。
2.8 聚合
Maven中的聚合,就是使用一个“总工程”将各个“模块工程”汇集起来,作为一个整体对应完整的项目。
- 项目:整体
- 模块:部分
2.8.1聚合的优点
- 一键执行Maven命令:很多构建命令都可以在“总工程”种一键执行。
- 配置聚合之后,各个模块工程在总工程中展示一个列表,让项目中的各个模块一目了然。
三、jar包下载失败问题解决方案
3.1 Maven正常下载的做法
- jar包在下载过程中,jar包的扩展名是XXX.jar.lastUpdated
- jar包下载成功后,Maven会将lastUpdated扩展名删除,让jar包恢复为XXX.jar。
3.2 Maven下载失败的情况
3.2.1 第一种情况
- jar包在下载过程中,jar包的扩展名是XXX.jar.lastUpdated
- 网络连接丢失,无法继续下载
- jar包没有下载完,lastUpdated扩展名不会被删除
- 要求Maven重新下载时,Maven看到这个jar包的扩展名是lastUpdated,Maven就不管了。
解决办法:
手动删除所有以lastUpdated结尾的文件,然后让Maven重新下载。
3.2.2 第二种情况
jar包表面上看起来是下载完的状态,结尾并没有“.lastUpdated”扩展名。但是程序运行时找不到这个jar包中的类。
解决办法:
找到“有嫌疑”的jar,确定其内部是否存在损坏问题。可以使用文件校验工具进行SHA1值对比。若比较结果一致,则jar包完好,否则jar包损坏。
找到有嫌疑的jar包的小窍门:
- 类所在的package命名往往和jar包坐标的groupId部分类似
- 在IDEA中按两下Shift键,使用全类名搜索,找到jar包后,右键-> Show in Explorer
- 如果前面的办法都没法定位,只能根据这个类看上去的特征和可能的功能找有可能有关的jar包
学海无涯苦作舟