dependency功能大幅度的简化了对第三方库的管理。如果需要将某个库升级到最新版本,只需要更改一下版本号。
传递性transitive
先看定义
可传递 如果A依赖B, B依赖C, 那么A也将依赖C
不可传递 A依赖B, B依赖C, 但是A不依赖C
第三方库,或者自己编写的java库,并不是每个功能都是完全重写一遍,还是有可能调用其它的一些开源库。这时就涉及到了依赖的传递性,它跟scope有关,见一下节。
查看项目的依赖关系, 可以使用命令
mvn dependency:tree
scope
限定在哪些情况下使用这个依赖库。
scope有五个值:
- compile, 默认值, 在mvn的编译/运行/测试/打包过程中, 都会将依赖加入到classpath, 在war包package过程中, 默认情况下会将依赖的库导入到war包的lib中。 compile类型的依赖是可传递的.
- provided,只在编译和测试阶段,将依赖加入到classpath, 在运行和打包时, 会忽略它们. 在运行时,需要jdk或是容器(例如tomcat, jetty)来提供这部分库 . provided类型的依赖不可传递。
- runtime,只是在运行和测试时, 才将依赖加到classpath. 比如, 通过配置文件/依赖注入/反射机制调用所依赖的库时, 可以使用runtime, 因为代码里没有直接引用依赖, 因此编译时不需要链接所依赖的库. runtime类型依赖是可传递的.
- test ,只是在测试阶段使用, 不可传递
- system, 类似于provided, 但是maven不会在仓库中搜索依赖, 而是需要使用systemPath(绝对路径)来指定搜索的目录. system类型依赖是可传递的.
如果嫌麻烦,可以不指定scope, 默认使用compile, 但是会导致生成的目标文件包含不必要的库。
另外, 部分插件可以使用scope过滤某些依赖。
dependencyManagement
可以将dependency的详细信息,包含version, scope定义在parent的pom.xml的dependencyManagement中, 而child的dependency只需要指定groupId和artifactId。此时version和scope将继承parent中的dependencyManagement对应的依赖项的值。相当于,由parent定义,然后由child引用。