maven的依赖调解机制

maven的依赖调解机制

本文目的

  上一篇,maven项目的结构为什么是这样的
  每个 maven项目中,会引用很多的第三方依赖,第三方依赖中可能又引用了其他的第三方,整个项目依赖分布图如下:
在这里插入图片描述
  从上图可以看出来,一个项目引用的依赖分布图,非常的“凌乱”,有的依赖有多个依赖入口。
  那就会有个问题,比如你自己依赖了gson包,而依赖的其他第三方依赖中也引用了gson,那项目最终会使用哪个?
在这里插入图片描述
   本文就解释这块,maven是怎么做的,这个在maven里称为依赖调解。以下内容参考学习《maven实战》。

正文

   在说依赖调解之前,首先要知道传递性依赖,即在maven中强大的scope标签详解中提到的。A引用了B包,B包里又引用了C包,如果在合适的依赖范围scope控制下,A同时就拥有了C包
   Maven引入的传递性依赖机制,一方面大大简化和方便了依赖声明,另一方面,大部分情况下,我们只需要关心项目的直接依赖是什么,而不需要考虑这些直接依赖会引入什么传递性依赖。但有的时候,当传递性依赖造成问题的时候,我们就需要清楚知道该传递性依赖是从哪条依赖路径引入的。(比如:jar包冲突,引入了版本过低的jar包造成异常)。

1. 依赖调解

   依赖调解maven对于引用重复依赖的一种选择机制。它主要有几个原则。

1.1 路径最近者优先

   比如下图:
在这里插入图片描述

   当在我们的pom.xml中存在两条路线对X(1.0)包的依赖,maven会遵循第一原则,路径最近者优先。从上图来看,优先采用下边A依赖-----X(1.0)

1.2 第一声明者优先

   当然只看路径最近者优先这个原则,肯定还不够,因为有可能正好两条路线长度都一样长。maven2.0.9版本之后,为了尽可能避免构建的不确定性,定义了第二个原则,第一声明者优先
   如下图所示:
在这里插入图片描述

   当两条对于X(1.0)X(2.0)两个版本的依赖路线长度相同,那因为D依赖声明在A依赖之前,因此优先引用的即D依赖X(1.0)这条线。

2. 自定义排包

   当然还有一种情况,如上图,存在X(1.0)X(2.0)的两个依赖,但是因为遵循了第二原则,X(1.0)会生效,但是我们又想使用X(2.0)包,那就需要自己在pom中,将第一条线里的X(1.0)版本排除掉。这个使用到了<exclusions>标签。举个栗子,如下:

 <!-- mybatis -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
            <exclusions>
                <exclusion>
                    <groupId>org.mybatis</groupId>
                    <artifactId>mybatis</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

   像上图的<exclusions>排包写法,mybatis-plus-boot-starter中排除掉对mybatis包的依赖。
   下一篇,maven项目打包构建的日志分析

猜你喜欢

转载自blog.csdn.net/wohaqiyi/article/details/119908921