目录
一 . lifecycle 生命周期
二. 依赖 与 依赖传递
三. scope 依赖范围
scope指定依赖范围
依赖传递依赖与原依赖冲突
四 maven的可选依赖与排除依赖
可选依赖 全部
排除依赖 显式的指定
maven官网技术文档:
一 . lifecycle 生命周期
* clean: 清理项目的包
* validate:验证工程是否正确,所有需要的资源是否可用。
* compile:
编译 项目的源代码。
* test: 使用合适的单元测试框架来测试已编译的源代码。这些测试不需要已打包和布署。
* package:把已编译的代码
打包成可发布的格式,比如 jar、war 等。
(* integration-test:如有需要,将包处理和发布到一个能够进行集成测试的环境。)
* verify: 运行所有检查,验证包是否有效且达到质量标准。
* install: 把包
安装
到maven
本地仓库,可以被其他工程作为依赖来使用。
* site: 生成站点文档(报告)等。
* deploy:发布。在集成或者发布环境下执行,将最终版本的包拷到
远程repository,使得其他工程或开发者可共享
二. 依赖 与 依赖传递
1 间接引入的依赖. 又叫
依赖传递依赖【因为 maven的
依赖 具有传递性!
]
当我们引入了一个依赖的时候,就会自动引入该依赖引入的所有依赖,依次往下引入所有依赖。比如我们引入了Druid数据库连接池的SpringBoot-Starter,就自动引入了该依赖依赖的依赖。总而言之就是套娃就完事了。
我们将这种依赖称为
间接引入的依赖.
2 直接依赖。
在pom文件中,直接用<dependency>标签中引入的依赖称为
直接依赖,
-
如果 直接依赖 和 间接引入的依赖 重复了并且版本不一样的话会怎么办呢?
以显式的 直接依赖为主。
-
如果 间接引入的依赖冲突了 (比如maven helper里看的 conflict的s),最后引入的到底是哪个版本呢,还是说都会引入呢?
如果是间接引入的(依赖传递的)重复了,遵从以下规则:
简单来说,就是越在外层的优先级越高,如果同级的就按照配置顺序,配置顺序靠前的覆盖配置顺序靠后的。
三. scope 依赖范围
scope指定依赖范围
首先,maven项目 如果不使用插件,依赖都不会被打包。 maven项目的依赖传递全靠pom.xml。
scope是指依赖范围, 作用于maven的周期。指定 某包的依赖范围。(并限定 那些包
依赖传递 的范围)
编译 compile 、 测试 test、 发布后运行 deploy。
依赖范围 就是用来 控制依赖 和
三种classpath (编译classpath,测试classpath、运行classpath)的关系,Maven有如下几种依赖范围:
【这里的
运行/打包deploy
和 在idea中
运行主程序main方法 不是一个概念。
】
-
compile : 【默认】 编译、测试、运行 依赖范围。
如果没有指定,就会
默认使用该依赖范围。 使用此依赖范围的Maven依赖,对于
编译、测试、运行三种
classpath都有效。典型的例子是spring-code,在编译、测试和运行的时候都需要使用该依赖。
典型的例子是: log4j。
-
test : 测试依赖范围 。 这个范围是不可传递的。
表示应用程序的正常使用时不需要依赖项,仅适用于测试编译和执行阶段。使用次依赖范围的Maven依赖,只对于
测试classpath有效,在编译主代码或者运行项目的使用时将无法使用此依赖。典型的例子是Jnuit,它只有在编译测试代码及运行测试的时候才需要。
典型的例子是: juint。
-
provided : 只是先编译着,运行时由容器提供。 编译和测试 。 这个范围是不可传递的。
使用此依赖范围的Maven依赖,对于
编译和测试 的classpath有效,但在运行时候无效。
表示您期望 JDK 或容器在运行时提供依赖项。
典型的例子是: servlet-api。 编译和测试项目时需要该依赖,但在运行项目时 由容器提供,不需要重复地import。
-
runtime: 有现成的不编译,在 测试和 运行时有效。
表示编译时不需要依赖,但执行时需要依赖。Maven 在
运行时和
测试类路径中包含对此范围的依赖项,但在
编译类路径中不包含此范围。
典型的例子是: jdbc。
依赖传递依赖与原依赖冲突
如果将 依赖项(横的一行)
设置为左列中的范围,则
该依赖项的
传递依赖项(左竖列)
与顶行的范围会导致主项目中的依赖项具有交叉点列出的范围。如果没有列出范围,则意味着省略了依赖项。
-
客(依赖项的传递依赖项)随主(当前依赖项)便 。当前项目指定下,传递依赖项只能取 两者指定范围的 交集(最小项)。
-
有冲突时(椭圆区)保持 原则不变。 当 当前依赖项 为runtime时,但 传递依赖项 为provided, 它 不是同样不需要依赖项,反而需要编译 只是运行时由容器提供。所以仍是provided( 依赖项自己不编译;但依赖传递项 编译时需要编译,但运行时由容器提供 == 假设传递依赖项不编译, 只保留依赖传递项的 依赖关系,让容器提供==provided )。
if 简化maven生命周期流程:
编译(主程序) -> 测试(测试程序) -> (部署)运行,
取值
|
适用范围
|
作用
|
compile
|
编译期、测试期、
运行期
|
默认 全部生命周期
|
test
|
测试期
|
表示正常使用时不需要。用于测试代码的编译和执行,如:junit
|
provided
|
编译期、测试期
|
表示先编译着,运行时由jdk等容器提供。对于
编译和测试 的classpath有效
|
runtime
|
测试期、
运行期
|
表示有现成的,不需要编译。测试和运行时需要。
|
网上说法众说纷纭,需要理解其本质,如下:
注意图中的 这个说法不太对的样子,官网上说明了 runtime包括测试类路径。如下:
四 maven的可选依赖与排除依赖
可选依赖 <optional>全部
可选依赖指对外隐藏当前所依赖的资源
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<optional>true</optional>
</dependency>
配置了该选项之后,junit这个包里的 间接依赖/传递依赖 就失效了。
排除依赖 <exclusion>显式的指定
显式地指定 排除某些依赖项(多用于版本冲突的时候)。
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<exclusions>
<exclusion>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
</exclusion>
</exclusions>
</dependency>
配置了该选项之后,指定的间接依赖/传递依赖 hamcrest-core也会失效。
maven官网技术文档:
Maven – Introduction to the Dependency Mechanism
Maven——依赖机制介绍