世人不熟知的dependencies和dependencyManagement的区别

前提

当我们将项目分成很多模块的时候,我们使用Maven管理项目非常方便。一般情况下,我们抽出一个父模块,然后将其他模块定义成子模块。为了项目的正确运行,必须让所有的子项目使用依赖项的统一版本,必须确保应用的各个项目的依赖项和版本一致,才能保证测试的和发布的是相同的结果;所以选择通过父模块来管理子模块的公共的依赖。也即为在父模块中定义公共依赖和其版本,在子项目中继承这些公共依赖供自己使用。父模块管理公共依赖可以通过在父模块的pom文件中使用以下两个元素:dependencies和dependencyManagement。

一、各自的作用

(1)、dependencyManagement:dependencyManagement里只是声明依赖,并不实现引入,而且子项目也不会直接默认继承声明的这些依赖;子项目中如果需要父中声明的某个依赖时,需要在子项目中显示的声明需要用的依赖(只写<groupId>和<artifactId>),无需显示的列出版本号,Maven会沿着父子曾子向上寻找拥有dependencyManagement元素的项目,然后使用它指定的版本号。如果不在子项目中声明依赖,是不会从父项目中继承下来的。另外如果子项目中需要该依赖,但是不需要父中指定的版本时,可以在子项目中声明该依赖的同时指定自己所需的版本号,这样以来,子项目中就会引入自己所需指定版本的的依赖了。

(2)、dependencies:相对于dependencyManagement,所有声明在dependencies里的依赖都会自动引入,并且默认被所有的子项目继承;意思是:即使在子项目中不写该依赖项,那么子项目仍然会从父项目中继承该依赖项(全部继承)。

二:对dependencyManagement的理解

(1)、在父模块中统一管理项目的版本号,避免在每个使用的子项目中都声明一个版本号,这样想升级或者切换到另一个版本时,只需要在父类容器里更新,不需要任何一个子项目的修改。

(2)、如果某个子项目需要另外一个版本依赖时,只需要在其pom文件中的dependencies中声明一个版本号即可;子类就会使用子类声明的版本号,不继承于父类版本号。

(3)、如果某个子项目中不需要父中声明的任何依赖,则在子项目中不引入任何父中的依赖即可,这样父中的依赖也不会被继承到子项目中;即按需拿取。

三:对dependencies的理解

(1)、我认为dependencies也是在父模块中统一管理项目的版本号,因为所有的子项目都默认继承了父中引入的依赖,所以当升级或者切换到另一个版本时,也只需要在父类容器里更新,不需要任何一个子项目的修改。

(2)、如果某个子项目需要另外一个版本依赖时,需要在其pom文件中引入另一个版本的依赖,但是会有问题,因为这时该模块中就会两个版本的依赖了,就有发生冲突的可能了。我试验的是当子模块中另行引入的版本小于父中的版本时,在打包时会报错;如果子模块中另行引入的版本大于父中的版本时,则打包时一切正常,且包中用的是高版本的依赖。不知道是不是这个版本冲突的原因。

(3)、不管子项目中是否需要父中引入的依赖,父中的所有依赖都会被所有子项目全部继承;这样以来子项目中的依赖就会很冗余。当子项目单独打包时,就会将那些不需要的依赖也打进去。我还没有给子模块打过包。

四:总结

当我们把项目分成多模块的子父模式时,多个子模块所需的公共依赖不可能完全一致,且某些子模块在引用某个依赖时,可能需要的版本不一致;所以在父模块中尽量使用dependencyManagement来声明所需要的公共依赖。

原文地址:https://www.cnblogs.com/hzcya1995/p/13302401.html