2. 依赖
依赖即:A->B,B->C,C->D这种项目间的依存关系。
在java的jvm内,依赖的最终表现是,项目A启动时,其依赖的jar包必须都对应放入其classpath路径内。
3. 依赖传递
上述过程中,项目Mall归结起来,依赖的fastjson会有三个版本。
而我们的jvm最终肯定只能接受一个版本的jar,所以必须有所取舍。
maven默认的取舍规则是:
1、路径最短原则:product和customer里的fastjson引用路径较短,路径为两步;pay项目里的fastjson引用路径较长,路径为三步。因此pay中的fastjson被淘汰;
2、同路径长度下,谁先声明谁优先:product和customer中的fastjson路径相同,那么就看在pom中是先声明product还是先声明customer,谁先用谁的。
4. 依赖冲突及解决
在依赖传递里,我们看到,maven根据自己的规则为我们取舍出了一个版本的jar,但此jar版本选择可能会与我们的项目预期不符:
例如:我们最终想的版本是fastjson:1.2.30版本(但它在第一步即被淘汰掉了)
当出现此类情况时,我们项目运行可能会出错(项目中使用到了1.2.30版本的特性),此问题即是我们常遇到的jar包冲突问题。
补救方式:使用exclusions将product和customer中的fastjson包排除掉,用法如下图:
当发生jar冲突程序报错时,可以使用mvn命令查出项目最终依赖的jar包树,看版本是否是我们预期的:
命令:mvn dependency:tree
5. 依赖范围scope
mvn在运行时,生命周期的不同阶段,会有不同的依赖范围,一般有以下依赖范围scope:
- compile:默认范围,用于编译(依赖的jar在打包时会包含进去)
- provided:类似于编译,但支持你期待jdk或者容器提供,类似于classpath(依赖的jar在打包时不会包含进去)
- runtime:在执行时需要使用(依赖的jar在打包时会包含进去)
- test:用于test任务时使用(依赖的jar在打包时不会包含进去)
- system:需要外在提供相应的元素。通过systemPath来取得(一般禁止使用)
每个scope实际上是配置了一个不同的classpath,jvm根据选择不同的classpath来达到依赖不同