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 个阶段

生命周期阶段描述
validate(校验)校验项目是否正确并且所有必要的信息可以完成项目的构建过程。
initialize(初始化)初始化构建状态,比如设置属性值。
generate-sources(生成源代码)生成包含在编译阶段中的任何源代码。
process-sources(处理源代码)处理源代码,比如说,过滤任意值。
generate-resources(生成资源文件)生成将会包含在项目包中的资源文件。
process-resources (处理资源文件)复制和处理资源到目标目录,为打包阶段最好准备。
compile(编译)编译项目的源代码。
process-classes(处理类文件)处理编译生成的文件,比如说对Java class文件做字节码改善优化。
generate-test-sources(生成测试源代码)生成包含在编译阶段中的任何测试源代码。
process-test-sources(处理测试源代码)处理测试源代码,比如说,过滤任意值。
generate-test-resources(生成测试资源文件)为测试创建资源文件。
process-test-resources(处理测试资源文件)复制和处理测试资源到目标目录。
test-compile(编译测试源码)编译测试源代码到测试目标目录.
process-test-classes(处理测试类文件)处理测试源码编译生成的文件。
test(测试)test(测试)
prepare-package(准备打包)在实际打包之前,执行任何的必要的操作为打包做准备。
package(打包将编译后的代码打包成可分发格式的文件,比如JAR、WAR或者EAR文件。
pre-integration-test(集成测试前)在执行集成测试前进行必要的动作。比如说,搭建需要的环境。
integration-test(集成测试)处理和部署项目到可以运行集成测试环境中。
post-integration-test(集成测试后)在执行集成测试完成后进行必要的动作。比如说,清理集成测试环境。
verify (验证)运行任意的检查来验证项目包有效且达到质量标准。
install(安装)安装项目包到本地仓库,这样项目包可以用作其他本地项目的依赖。
deploy(部署)将最终的项目包复制到远程仓库中与其他开发者和项目共享。

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 . 最短路径者优先原则

有图片

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 . 先声明者优先原则

有图片

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 的依赖 <dependencies > </dependencies > 里面, 先放置哪一个,就用哪一个。 你先放置 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(系统依赖) 目前用不到,老蝴蝶也不知道,就不讲解了。

总结成一张图就是:

有图片

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

有图片

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

二.三 手动排除依赖

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

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

有图片

选中 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 这个 依赖了。

谢谢!!!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

两个蝴蝶飞

你的鼓励,是老蝴蝶更努力写作的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值