Maven的生命周期和依赖传递(四)

简介: Maven的生命周期和依赖传递(四)

一. Maven的生命周期


我们在第二章时,输入的那些命令,如 clean(清理),compile (编译),

test(测试),package(打包),install(安装) ,可以被 Maven 处理并且运行, 这些命令是什么? 其实这些命令都是 Maven的生命周期。 生命周期, Servlet 有生命周期, 多线程也有生命周期, Maven自然也有生命周期。


Maven 有三个标准的生命周期


clean 周期, default 周期, site(站点) 周期。


1 . clean : 项目清理的处理


2 . default 默认周期,对项目部署的处理,最主要的。


3 . site 项目站点文档创建的处理


这三个生命周期,是完全不同的生命周期,针对的不是一件事。 clean 是管 项目的清理的, default 是管项目的部署的, site 是管站点文档创建的。


一.一 clean 生命周期

clean 清理生命周期,包括三个阶段:


1 . pre-clean : 执行一些需要在 clean (第二阶段)之前执行的操作


2 . clean : 移除所有上一次构建所生成的文件。 一般指 target 目录


3 .post-clean: 执行一些需要在 clean(第二阶段) 之后执行的操作


在执行各个阶段时,不论是 clean 周期,还是 default, site 周期, 执行后面的阶段,一定会把前面的阶段先执行。


即: 如果我们执行 mvn clean 命令, 就会把 pre-clean 阶段也执行,并且是优先于 clean 执行


mvc clean= mvc pre-clean clean 命令。


mvc post-clean= mvc pre-clean clean post-clean


故记住生命周期的阶段顺序是很有必要的。


一.二 default 生命周期


默认生命周期,是maven 的主要周期,主要用于对项目的 验证,编译,测试,打包,安装,部署 等主要的操作。


下面的这些命令太长,直接从 菜鸟教程的 Maven系列的 Maven 构建生命周期 一章摘录。 (菜鸟教程,一个很好的学习网站)


共 23 个阶段


image.png


image.png


1 .阶段很多啊,不需要我们全部忘记, 只需要记住一些常用的就可以了。


常用的有: validate,compile, test, package, verify,install, deploy


2 .我们运行后面的阶段,会自动将前面的阶段全部运行。


相对的,运行某个命令出错,不一定是这个命令千万了出错,也可能是前面的出错了。 如 运行 package 打包命令出错了,不一定说是 package命令一定出错了, 可以是前面的 compile 或者 test 出错了,导致后面的阶段无法运行。


3 .在运行的时候,可以同时运行一个生命周期的不同阶段,


如 mvn compile test, mvc compile package


这样的命令是可以的, 但不建议这么使用。


4 .Maven 在运行时,可以跨生命周期进行运行,如同时运行 clean周期和default 周期。


mvn clean package, mvn clean test 是完全可以的。


先进行清理,再进行打包, 先进行清理,再进行测试。


一.三 site 生命周期

用来创造新的报告文档和部署站点。


共有四个阶段:


1 .pre-site 执行一些需要在生成站点文档之前完成的工作


2 .site 生成项目的站点文档


3 .post-site :执行一些需要在生成站点文档之后完成的工作,并且为部署做准备


4 . site-deploy: 将生成的站点文档部署到特定的服务器上


常用的是 site 和site-deploy.


二. 依赖


二.一 jar包依赖规则


有时候, 一个 jar包 不可能办成所有的事情,如文件上传的 common-fileupload.jar 包,只是完成了文件上传的部分,关于文件的复制之类的操作代码,并没有完成,而是依赖于 common-io.jar 包。 common-fileupload.jar 需要依赖于 common-io.jar包而存在, 即 如果你只添加了 common-fileupload.jar包,而不添加 common-io.jar包,那么系统会报错,报 ClassNotFoundException, 像这样的关系,叫做直接依赖。 项目A引用了项目B,那么项目B就是项目A的直接依赖。 有了直接依赖,那么就有间接依赖。项目A引用了项目B,而项目B又引用了项目C,那么项目C就是项目A的间接依赖。 当直接依赖和间接依赖多的时候,就容易出现问题。


在一个项目里面,有很多的框架组成,如小型的 SSM框架。 里面有很多的jar包, Spring直接依赖于 某些jar包,如 日志类的, MyBatis 直接依赖于某些 Jar包,也有日志类的, Spring直接依赖的jar包与MyBatis直接依赖的Jar包 可能会有重复, 那么这些重复的jar包,该导入哪些呢,是导入Spring的,还是导入MyBatis的呢? 这只是直接依赖,还有可能有间接依赖, 如Spring间接依赖的jar包,与MyBatis间接依赖的jar包有重复,该用哪些呢? 该用哪些,实际上就是制定一些规则。 Maven导入jar包时,会自动将其依赖的jar包导入进来,且各个依赖包不造成冲突,就是因为这些规则.


Maven的依赖规则有两个,也是符合现实情况的:


1 . 最短路径者优先原则


20191024125812127.png


A直接依赖于B, B直接依赖于C, 那么A间接依赖于 C


B直接依赖于 D, C 直接依赖于D, A对D都是直接依赖,


那么A依赖于的是哪个 D呢?


就像走路一样, 走哪儿,能更快到 D呢? 当然是 A–B--D 的路径,而不是 A–B--C-D的路径。


所以, A最后用的是 B依赖的 D jar包。


2 . 先声明者优先原则


20191024125818541.png


A直接依赖于B, B依赖于D, A间接依赖于D.


A直接依赖于C, C依赖于D, A 间接依赖于D.


A–B--D, A—C---D, 长度都一样,最短路径者优先原则不符合了。 这个是,谁先说去哪,就去哪。 即,用户者说走 A–B--D,那么就用 B依赖的 D, 用户者说走 A–C--D,那么就用 C依赖的 D. 用户说走哪,是默认根据 用户先声明的哪决定的。


在pom.xml 的依赖   里面, 先放置哪一个,就用哪一个。 你先放置 B, 那么D就是 B里面的, 你先放置 C, 那么D就是C 里面的。 所以在放置 依赖时,有一定的顺序。


这两个原则, 是Maven 自己在找 jar包时依据的,与用户没有多大关系,用户不需要关心这个依赖规则,但必须要知道这两个依赖规则。


下面这一个,才是与用户有关的,且必须要劳劳记住的。


二.二 Jar包的依赖范围


测试的jar包,如 junit4.12, 只希望在代码测试的时候使用,不希望在布署项目的时候 把这个jar包放置上去,这样可以减少资源, tomcat的jar包, server-api.jar, jsp-api.jar 在代码编译的时候有用,但在布署项目的时候,是没有的用的,并且是不能 把这个两个 jar包放置到tomcat里面的,因为tomcat 里面有这两个 jar包,会造成冲突, 所以一定要把这两个jar包 给去掉。 那这种情况该怎么办呢? 配置的依赖 jar包要是有一定的 使用范围就好了, 就就是 依赖范围。


依赖范围有六种: compile, test, provided, runtime, import,system, 其中最常用的是 test 和provided,runtime


1 .complie 编译依赖, 是默认的依赖范围。 在main 目录下的代码可以访问这个范围下的依赖,即jar包。 test 目录下的代码也可以访问这个范围下的依赖。 布署到 tomcat下时, 要把这个依赖放置在 WEB-INF 下的 lib 文件夹里面。


2 . test 测试依赖,仅仅是测试使用的。 在main目录下的代码不能访问这个依赖, test 目录下的代码可以访问这个依赖, 布署到tomcat下时, 不会把这个依赖放置在 WEB-INF下的 lib文件夹里面。 如 junit 4.12 这个依赖。


3 .provided 提供依赖 在main目录下的代码可以访问这个依赖, test目录下的代码也可以访问这个依赖, 但在布署到tomcat下时,不会把这个依赖放置在 WEB-INF 下的lib文件夹里面。 如 servlet-api, jsp-api


4 .runtime 运行依赖。 main目录下的代码不能访问这个依赖, test目录下的代码可以访问这个依赖, 布署到tomcat下时,会把这个依赖放置在 WEB-INF 下的lib 文件夹里面。 如 jdbc 驱动


5 . import(导入依赖) 和system(系统依赖) 目前用不到,老蝴蝶也不知道,就不讲解了。


总结成一张图就是:


20191024125828668.png


上面的这些,是直接依赖的范围。 还有间接依赖的范围。


20191024125834933.png


A 直接依赖于B,间接依赖于 C,D,E, 如果C 为complie, 那么A可以使用, D为 test,E 为provided 那么 A不能使用。


二.三 手动排除依赖


在 二.一 讲解的依赖原则时, Maven会根据 最短路径者优先原则和 先声明者优先原则 两个原则,来决定选用哪个依赖。 但是,要保证一点,这两个依赖 的坐标,包括版本号 要完全一样, 这样Maven 才认为两个是相同的,才会选择其一。 但如果两个依赖的坐标,常见的是版本不一样,那么这个时候,Maven 就会把两个依赖都导入进来。 很显然,两个不同版本号的 jar包放在一起,很有可能会出现问题,所以就需要手动排除依赖了。


选中 pom.xml 文件, 选择第三个选项卡 Dependency-Hierarchy , 找到那个版本不一致的 jar包, 如 spring-beans


2019102412585080.png


选中 Exclude Maven Artifact ,进行排除即可


查看 pom.xml 文件:


<dependency>
      <groupId>org.apache.struts</groupId>
      <artifactId>struts2-spring-plugin</artifactId>
      <version>2.3.24</version>
      <exclusions>
        <exclusion>
          <groupId>org.springframework</groupId>
          <artifactId>spring-beans</artifactId>
        </exclusion>
      </exclusions>
    </dependency>


用 exclusion 进行排除依赖


这样在 struts2-spring-plugin 里面就不会有 spring-beans 这个 依赖了。


谢谢!!!

相关文章
|
8天前
|
缓存 架构师 Java
Maven实战进阶(01)面试官:Maven怎么解决依赖冲突?| 有几种解决方式
本文介绍了Maven的核心功能和依赖管理技巧。Maven是基于项目对象模型(POM)的构建工具,具备跨平台、标准化、自动化等特性。其三大核心功能为依赖管理、仓库管理和项目构建。依赖管理通过pom.xml文件引入第三方组件并自动下载;仓库管理涉及中央仓库、私服和本地仓库;项目构建则通过生命周期管理编译、测试、打包等流程。文章还详细讲解了依赖冲突的解决方法,包括默认规则、手工排除和版本指定等策略。
|
30天前
|
缓存 Java Maven
【简单四步教你解决♥十分有效】Maven依赖报错、依赖或插件导入失败的万能解决办法
【简单四步教你解决♥十分有效】Maven依赖报错、依赖或插件导入失败的万能解决办法!在处理Maven项目问题时,首先检查Maven配置是否正确。接着通过“File--Invalidata Caches”清除IDEA缓存并重启。使用Maven命令`mvn dependency:purge-local-repository`和`mvn dependency:resolve`清除本地依赖缓存。最后,在Terminal中输入`mvn clean install`完成构建。
【简单四步教你解决♥十分有效】Maven依赖报错、依赖或插件导入失败的万能解决办法
|
5月前
|
Java Maven 容器
java依赖冲突解决问题之Maven在编译打包过程中对依赖的jar包如何解决
java依赖冲突解决问题之Maven在编译打包过程中对依赖的jar包如何解决
|
1月前
|
Java Maven
Maven的生命周期
Maven生命周期分为清理、构建和站点生成三部分,每部分含多个固定顺序执行的阶段。清理包括pre-clean和clean;构建涵盖validate、compile、test、package、install及deploy;站点生成则有pre-site、site、post-site与site-deploy。
67 6
|
2月前
|
Java Maven
maven打瘦包,且只打入部分想打入的依赖瘦包
maven打瘦包,且只打入部分想打入的依赖瘦包 设计 工程结构分析 环境管理 城市资源 安全工程 工程管理
80 10
|
3月前
|
Java API Apache
除了 Maven,还有哪些工具可以管理项目的依赖和版本冲突
除了Maven,常用的项目依赖管理和版本冲突解决工具有Gradle、Ivy、Ant+Ivy、SBT等。这些工具各有特点,适用于不同的开发环境和需求。
264 2
|
3月前
|
XML 安全 Java
【Maven】依赖管理,Maven仓库,Maven核心功能
【Maven】依赖管理,Maven仓库,Maven核心功能
868 3
|
3月前
|
Java Maven
Maven 依赖管理
Maven 一个核心的特性就是依赖管理。当我们处理多模块的项目(包含成百上千个模块或者子项目),模块间的依赖关系就变得非常复杂,管理也变得很困难。针对此种情形,Maven 提供了一种高度控制的方法。
185 5
|
4月前
|
Java Maven
Maven 引入外部依赖
如果我们需要引入第三方库文件到项目,该怎么操作呢?
61 5
|
5月前
|
安全 Java Maven
优化Maven镜像配置:使用阿里云加速依赖下载
更新Maven镜像配置至关重要,尤其使用阿里云仓库时。在`settings.xml`中加入特定镜像配置可显著提升依赖下载速度。示例配置指定了阿里云镜像ID、替代表态仓库、安全的URL、默认布局及启用版本管理。需定位至用户目录下的`.m2/`文件夹编辑`settings.xml`,添加镜像信息后保存测试。若下载仍慢,考虑网络状况或备选镜像。多镜像设置时需注意避免冲突。
908 3