Maven依赖关系原则(概念):

相关概念:

级别:

        我们不妨把pom.xml里面的引用的依赖视为第一级,那么依赖中各自引用的依赖视为第二级...第三级...

路径长短:

        我们不妨以从pom.xml出发,到抵达该依赖时经过的“级”的个数来作为路径长短的标准。

最短路径(不同级引用)原则:

若两个版本不同的同一依赖,在不同的级别中,那么优先使用路径最短的那一个,如:

PGobject的maven依赖_jar包

同级(第一级遵循最后、其它级遵循最先)引用原则:

同级别的引用,分两种:
       两个不同版本的同一依赖,所在的级别是第一级;两个不同版本的同一依赖,所在的级别不是第一级。

  • 在第一级,谁后声明,使用谁:

PGobject的maven依赖_PGobject的maven依赖_02

  • 不在第一级,谁先声明,使用谁:

Maven依赖关系原则(测试验证):

提示:这里只给出测试原理及结果,具体的测试代码、测试项目本人托管在Github上,具体链接见本文末尾。

  • 测试项目结构及测试原理说明:

PGobject的maven依赖_jar包_03

        fastjson-1.2.10版本与fastjson-1.2.11版本差别较大,如果是1.2.11版的话,可以在代码中直接new FastJsonConfig();而如果是1.2.10版的话,直接在代码中new FastJsonConfig()的话,是会报错的。在这个的基础上,我们可以通过在a模块儿中直接或间接(通过引入其他模块儿来)引入fastjson的依赖,来判断maven最终引用的是哪一个版本的依赖,进而测试上面的结论。

  • 测试最短路径:

PGobject的maven依赖_Management_04

  • 测试(第一级)最后引用:
     

PGobject的maven依赖_Management_05

  • 测试(非第一级)最先引用:

PGobject的maven依赖_maven_06

注:按本文中约定的定义,上图中的依赖关系中,d、e是第一级别,fastjson是第二级别。


Maven(依赖)冲突解决办法:

第一种:使用【exclusions】排除不需要的依赖。

PGobject的maven依赖_jar包_07

第二种:使用【dependencyManagement】指定使用哪一个版本的依赖。

PGobject的maven依赖_PGobject的maven依赖_08

注:dependencyManagement的作用有两个:一是指定使用某个依赖的哪一个版本。二是统一管理版本
        在dependencyManagement指定版本号后,在与dependencyManagement同级的
        dependencies标签里面,引入依赖时,就可以不指定版本号了。

注:maven官网是这么介绍Dependency Management的:

Dependency Management

        Besides inheriting certain top-level elements, parents have elements to configure values for child POMs and transitive dependencies. One of those elements is dependencyManagement.

        dependencyManagement: is used by a POM to help manage dependency information across all of its children. If the my-parent project uses dependencyManagement to define a dependency on junit:junit:4.12, then POMs inheriting from this one can set their dependency giving the groupId=junit and artifactId=junit only and Maven will fill in the version set by the parent. The benefits of this method are obvious. Dependency details can be set in one central location, which propagates to all inheriting POMs.

        Note that the version and scope of artifacts which are incorporated from transitive dependencies are also controlled by version specifications in a dependency management section. This can lead to unexpected consequences. Consider a case in which your project uses two dependences, dep1 and dep2. dep2 in turn also uses dep1, and requires a particular minimum version to function. If you then use dependencyManagement to specify an older version, dep2 will be forced to use the older version, and fail. So, you must be careful to check the entire dependency tree to avoid this problem; mvn dependency:tree is helpful.

第三种(必杀):直接在jar包中删除冲突了的(多余的那个依赖)对应的package包。

        第一种第二种方式就能解决所有maven管辖范围内的依赖冲突了。大部分难以解决的冲突,几乎都是由于引入了jar包而引起的。这里介绍如何解决jar包引起的冲突:使用解压工具(如rar)直接删除jar包里面的不需要的依赖对应的包

场景举例说明:

       笔者最近使用使用到了某考勤厂商的sdk依赖jar包。该jar包有点特殊,是由gradle构建的,而且貌似构建得不规范;本人将其引入SpringBoot项目后,发生冲突了,需要将该jar包里面的低版本的fastjson去掉;第一种第二种方式都试了,再网上找了一圈页眉找到有效的解决办法,然后回头一想:只要当前环境中存在该jar包需要的依赖就可以了,至于在不在该jar里面就无所谓了,所以我直接使用rar删除了该jar包里面不要的fastjosn包,然后重新将jar包导入项目,冲突就解决了。

PGobject的maven依赖_json_09

PGobject的maven依赖_json_10

删除后,关闭。再次打开jar包,发现fastjson对应的包已经没了。