Maven传递性依赖解读

一:DependencyManagement / Dependencies的区别

dependencyManagement统一管理项目的版本号,只声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。在子项目中写了该依赖项,并且没有指定具体版本,会自动从父项目中继承该项,并且version和scope都读取自父pom;  另外如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。

所有声明在dependencies里的依赖都会自动引入,并默认被所有的子项目继承。一般webapp的pom不能直接写dependencies,需嵌套在dependencyManagement中。

二:3种特殊范围声明

compile:编译依赖范围。如果没有指定,就会默认使用该依赖范围。使用此依赖范围的Maven依赖,对于编译、测试、运行三种classpath都有效。典型的例子是spring-core,在编译,测试和运行的时候都需要使用该依赖。
provided:已提供依赖范围。使用此依赖范围的Maven依赖,对于编译和测试classpath有效,但在运行时无效。典型的例子是servlet-api,编译和测试项目的时候需要该依赖,但在运行项目的时候,由于tomcat容器已经提供,就不需要Maven重复地引入一遍。
test:测试依赖范围。使用此依赖范围的Maven依赖,只对于测试classpath有效,在编译主代码或者运行项目的使用时将无法使用此类依赖。典型的例子就是JUnit,它只有在编译测试代码及运行测试的时候才需要。
 

例如:在dependencyManagement中声明:

Maven传递性依赖解读_第1张图片

 

三:依赖关系

1).短路优先:谁离得最近就使用谁的依赖jar包

C到达A为C->B->A

C到达B为C->B

例如:

A中的 commons-io的版本为2.4

B中的commons-io的版本为2.0

C中依赖于B,B依赖于A

则C的junit的包为2.0版本

因为依赖的短路优先

2).如果两条路都是一样长的时候呢?

C到达A为C->A

C到达B为C->B

则看pom文件中依赖的两个工程谁在前面就是用哪个版本。但不一定生效 , 往往是这种路径一致造成jar冲突。

fee-facade:关系图:可以看到引入了m-commons。

Maven传递性依赖解读_第2张图片

但是在webapp实际引用关系图中fee-facade下层并没有出现m-commons。

Maven传递性依赖解读_第3张图片

可以查一下m-commoms实际上在这被引用,是被bprod-facade带进来的。离根部距离为2,而fee-facade离根部距离为2,所以它的m-commms距离为3。所以根据就近原则。真实引用的为距离为2的m-commoms。

Maven传递性依赖解读_第4张图片

四:jar包冲突

如果项目同时依赖两个子项目的某个包,路径一样且版本号不一致。编译打包后target目录生成了2个不同版本的jar包。运行时候会报错。我们可以通过报错信息在依赖关系图中找到真实的引用。制定新版本或者把低版本的jar包exclude掉。

Maven传递性依赖解读_第5张图片

 

你可能感兴趣的:(编码之路)