Maven依赖调解和可选依赖

Maven依赖调解

Maven引入的传递性依赖机制,一方面大大简化和方便了依赖声明,另一方面,大部分情况下我们只需要关心项目的直接依赖是什么,而不用考虑这些直接依赖会引入什么传递性依赖。但有时候,当传递性依赖造成问题的时候,我们就需要清楚的知道该传递性依赖是从哪条依赖路劲引入的。

例如,项目A有这样的依赖关系:A->B->C->X(1.0)、A->D->X(2.0),X是A的传递性依赖,但是两条依赖路径上有两个版本的X,那么哪个X会被Maven解析使用呢?两个版本都解析显然是不对的,因为会造成重复依赖,因此必须选择一个。Maven依赖调解的第一原则是:路劲最近者优先,该例中X(1.0)的路径长度为3,而X(2.0)的路径长度为2,因此X(2.0)会被解析使用。

依赖调节第一原则不能解决所有的问题,如果两条依赖路径的长度是一样的呢?那到底谁被解析使用呢。Maven的依赖调解的第二原则:第一声明者优先。在依赖路径相等的情况下,在POM中依赖声明的顺序决定了谁会先被解析使用,顺序前的先解析使用。

可选依赖

假设有这样一个依赖关系,项目A依赖于项目B,项目B依赖于项目X和Y,B对于X和Y的依赖都是可选依赖:A->B、B->X(可选)、B->Y(可选)。根据传递性依赖的定义,如果所有这三个依赖的范围都是compile,那么X、Y就是A的compile范围的传递性依赖。然而,由于这里X、Y是可选依赖,依赖将不会得以传递。换句话说,X、Y将不会对A有任何影响。

为什么要使用可选依赖这一特性呢?可能是项目B实现了两个特性,其中的特性一依赖于X,特性二依赖于Y,而且这两个特性是互斥的,用户不可能同时使用这两个特性,比如B是一个持久层隔离工具包,它支持多种数据库包括:MySQL,PostgreSQL等,在构建这个工具包的使用,需要这两种数据库的驱动程序,但是在使用这个工具包的时候,只会依赖一种数据库。
Maven依赖调解和可选依赖_第1张图片

可选依赖的配置

Maven依赖调解和可选依赖_第2张图片

上述XML代码片段中,使用元素表示mysql-connect-java和postgresql这两个依赖为可选依赖,他们只会对当前项目B产生影响,当其他项目依赖于B的时候,这两个依赖不会被传递,因此,当项目A依赖于项目B的时候,如果其实际使用基于MySQL数据库,那么在项目A中就需要显示地声明mysql-connect-java这一依赖。
Maven依赖调解和可选依赖_第3张图片

在理想的情况下,是不应该使用可选依赖的,而是应该为MySQL和PostgreSQL分别创建一个Maven项目,基于同样的groupId分配不同的artifactId,在各自的POM中声明JDBC驱动依赖,而且不使用可选依赖,用户则需要根据选择使用依赖。由于传递性依赖的作用,就不需要在声明JDBC驱动依赖。

你可能感兴趣的:(Maven,maven)