Maven基础

1.概述

 2.使用Maven的背景

(1)一个项目就是一个工程

如果项目非常庞大,就不适合继续使用package来划分模块,最好是每一个模块对应一个工程,利于分工协作。

借助于Maven就可以将一个项目拆分成多个工程

(2)项目中需要的jar包必须手动“复制”,"粘贴"到WEB-INF/lib目录下

带来的问题是:同样的jar包重复出现在不同的项目工程中,一方面浪费存储空间,另外也让工程比较臃肿。

借助于Maven,可以将jar包仅仅保存在"仓库"中,有需要使用的工程引用这个文件接口,并不需要真的把jar包复制过来

 

(3)jar包需要别人替我们准备好,或到官网下载

不同技术的官网提供jar包下载的形式是五花八门的。

有些技术的官网就是通过Maven或SVN等专门的工具来提供下载的。

如果是以非正规的方式下载的jar包,那么其中的内容很可能也是不规范的。

借助于Maven可以以一种规范的方式下载jar包,因为所有知名框架或第三方工具的jar已经按照统一的规范存在了Maven的中央仓库中。以规范的方式下载的jar包,内容也是可靠的。

(4)一个jar包依赖其他jar包需要自己手动加入到项目中

如果所有的jar包之间的依赖关系都需要程序员自己非常清楚了解,那么就会极大增加学习成本。

jar包往往不是孤立存在的,很多jar包都需要在其他jar包的依赖下才能正常工作,我们称之为jar包的依赖关系。

例如:commons-fileupload-1.3.jar依赖于commons-io-2.0.1.jar,如果没有IO包,FileUpload包就不能正常工作。

Maven会自动将被依赖的jar包导入进来

 3.Maven是什么

(1)Maven是一款服务于Java平台的自动化构建工具,是一个项目管理工具,主要作用是在项目开发阶段对Java项目进行依赖管理项目构建

 (2)依赖管理:就是对jar包的管理。通过导入maven坐标,就相当于将仓库的jar包导入当前的项目中

(3)项目构建

  概念:以"Java源文件"、"框架配置文件"、"JSP"、"HTML"、"图片"等资源为原材料,去生产一个可以运行的项目的过程。

  • 编译
  • 部署
  • 搭建

  编译:Java源文件【user.java】->编译->Class字节码文件【User.class】->交给JVM去执行

  部署:一个BS项目最终运行的并不是动态Web工程本身,而是这个动态Web工程"编译的结果"

     生的鸡 ->处理->熟的鸡

    动态Web工程->编译,部署->编译结果

在开发过程中,所有的路径或配置文件中配置的类路径等都是以编译结果的目录结构为标准的

 

 上面的画框的是运行时环境,其实是一组jar包的引用,并没有把jar包本身复制到工程中,所以并不是目录。

(4)构建过程

  • 清理  将以前编译得到的旧的class字节码文件删除,为下一次编译做准备
  • 编译  将Java源程序编译成class字节码文件,即src目录下的源码进行编译,编译成class字节码文件
  • 测试    自动测试,自动调用JUnit程序
  • 报告    测试程序执行的结果
  • 打包    动态web工程打war包,Java工程打jar包
  • 安装    Maven特定的概念,将打包得到的文件复制到“仓库”中的指定位置,即将我们当前开发的maven项目,打成包,并且安装到本地仓库
  • 部署    将动态web工程生成的war包复制到Servlet容器指定的目录下,使其可以运行

(5)自动化构建

 

4.Maven仓库类型

1.本地仓库

2.远程仓库
  (1)maven中央仓库(地址:http://repo2.maven.org/maven2/)可以在后面这个网站上找jar包,https://mvnrepository.com/

  (2)maven私服(公司局域网的仓库,需要自己搭建)

  (3)其他公共远程仓库(例如Apache提供的远程仓库,地址:https://repo.maven.apache.org/maven2/)

5.Maven坐标书写规范

主要是在pom.xml中定义这些坐标,严格按照这样的方式书写

 6.Maven的依赖范围

 有效的意思就是对于某个目录是否能够识别到某个jar包

举例说明:

 上面那样写,意思是,Junit的依赖范围是compile,即默认的范围是compile,compile对应的目录是main下面的,在我们的main目录和test目录下都可以识别到这个jar包的

接下来我们来指定scope,scope代表的是maven的依赖范围,scope中写test,这样对于main那个目录就无效了。

可以看到scope中加入test,main目录就不能识别Junit的jar包了,即对编译的classpath无效

7.Maven的依赖传递

 在maven中,依赖是可以传递的,假设存在三个项目,分别是项目A,项目B,项目C。假设C依赖B,B依赖A,那么我们可以根据maven项目依赖的特征不难推出项目C也依赖A

 

导入spring-webmvc的jar包,也会把下面的也导入进来,也就是从spring-webmvc传递过来的

因此maven的依赖传递,就是jar包的传递

通过上面的图可以看到,我们的web项目直接依赖了spring-webmvc,而spring-webmvc依赖了spring-aop,spring-beans等。最终的结果就是在我们的web项目中 间接依赖了spring-aop,spring-beans等。

8.依赖冲突

 

8.1 如何解决依赖冲突

8.1.1 使用maven提供的依赖调解原则

  • 第一声明者优先原则
  • 路径近者优先原则

(1)第一声明者优先原则

在pom文件中定义依赖,以先声明的依赖为准。其实就是根据坐标导入的顺序来确定最终使用哪个传递过来的依赖

 

这个案例中以上面的spring-beans:4.1.3版本为准,其实就是因为先导入spring-webmvc,后导入spring-aop的

 

我们调换一下顺序

 

这样下面jar包的顺序也就变了

这时候就是以上面的spring-beans:5.0.5为准了

 但是这种方式,在一旦我们的坐标很多的时候,需要很多地方调整顺序的时候,就不行了。

(2)路径近者优先原则

在pom文件定义依赖,以路径近者为准。

还是上述情况,spring-aop和spring-webmvc都会传递过来spring-beans,那如果直接把spring-beans的依赖写的pom文件中,那么项目就不会再使用其他依赖传递过来的spring-beans,因为自己直接在pom定义spring-beans要比其他依赖传递过来的路径要近。

 

 8.1.2 排除依赖

可以使用exclusions标签将传递过来的依赖排除出去

 

 将spring-webmvc中的spring-beans排除掉,这样就以spring-aop中的spring-beans为准了

这种方式一般使用

8.1.3 版本锁定(重点掌握)

采用直接锁定版本的方法确定依赖jar包的版本,版本锁定后则不考虑依赖的声明顺序或依赖的路径,以锁定的版本为准添加到工程中,此方法在企业开发中经常使用

版本锁定的使用方式:

第一步:在dependencyManagement标签中锁定依赖的版本

第二步:在dependecies标签中声明需要导入的maven坐标

下面演示一下:

  • 在dependencyManagement标签中锁定依赖的版本

 

 注意:pom文件中使用dependencyManagement标签进行依赖jar的版本锁定,并不会真正将jar包导入到项目中,只是对这些jar的版本进行锁定。项目中使用那些jar包,还需要在dependencies标签中进行声明

  •  在dependecies标签中声明需要导入的maven坐标

 

posted @ 2020-09-16 11:03  GumpYan  阅读(106)  评论(0编辑  收藏  举报