一、什么是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包

学海无涯苦作舟