我们经常写Maven
依赖。很少去关注Maven
依赖的作用域问题,更多的关注的所依赖jar包的版本问题。
比如我们在pom文件中加入一个依赖,一般都是这样写。
1 | <dependency> |
里面根本没有体现作用域的信息。所以很多人不是很关心依赖的作用域。其实上面这个依赖的作用域是compile
的。因为Maven
是约定大于配置,所以上面这个pom依赖是使用了默认的依赖作用域。
下面来简单总结一下Maven
依赖的作用域。要想说明白作用域问题,先得弄清楚Maven
项目的生命周期。大致可以分为这么几个阶段 编译》测试》打包》运行 。
Maven
依赖的作用域范围可以表示为 compile,test,runntime,provided,system
。
compile
最常用的就是compile
,如果不配置scope
项则默认就compile
的。compile
表示被依赖的Jar包,参与当前项目的编译,并且后续的测试和运行阶段也参与其中。
test
表示依赖项目仅参与测试阶段相关的工作,包括测试代码的编译,执行。比如1
2
3
4
5
6<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
runntime
表示依赖项目并不参与项目的编译阶段工作,但是后续的测试和运行阶段的工作要其参与其中。这个作用域日常工作中使用的比较少。
provided
provided
作用范围跟compile
类似,唯一的区别就是在打包的时候会跳过作用域是provided
的项目,也就是最终不会被打进Jar包。比如1
2
3
4
5
6<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-streaming_2.11</artifactId>
<version>2.4.4</version>
<scope>provided</scope>
</dependency>
因为spark的运行环境会提供spark-streaming的相关jar包,所以无需一起打包。
system
与provide
的作用范围类似,唯一的区别就是不会从Maven
仓库抓取Jar包,而是从本地文件系统获取。日常工作很少用到。
scope
的依赖传递问题
假设当前项目为A,A依赖于B,B依赖于C。如果知道B在A项目中的scope
,那么怎么知道C在A中的scope
呢?
如果当C是test
或者provided
时,C直接被丢弃,A不依赖C;否则A依赖C,C的scope
继承于B的scope
。