一般我们在 Maven 管理的项目中会看到 dependencies 的使用,通过这个标签,来管理依赖。
<dependencies>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
<version>3.17version>
dependency>
dependencies>
但是会出现一些弊端:
1.在多模块的项目中,如果父 pom 中引入依赖,则子模块会全盘接受父 pom 中引入的依赖,即使它本身不需要这个依赖。如果子模块单独启动或打包的话,速度变慢、打的jar臃肿。
2.为了避免第一个问题,则在子模块中进行所需依赖。但是如果,其他子模块也需要这个依赖时,不注意就容易造成版本冲突。
因此才有了 dependencyManagement。
这个标签在多模块的项目尤其好用。
一般是用在父 pom 中的。
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<version>2.1.9.RELEASEversion>
<scope>testscope>
<exclusions>
<exclusion>
<groupId>com.vaadin.external.googlegroupId>
<artifactId>android-jsonartifactId>
exclusion>
exclusions>
dependency>
dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
<version>3.17version>
dependency>
dependencies>
dependencyManagement>
在父 pom 中声明了上述的依赖,实际不会直接真实导入依赖。而只是一个声明的作用。
使用 Maven Helper 查看一下父级 pom。
可以看到,只有通过 dependencies 引入的依赖。
子模块 pom 可以根据需要,只声明对应的 groupId 和 artifactId 来引入依赖。而省略的 version 和 scope,会沿着树向上层 pom 查找最近的 dependencyManagement 声明的 groupId 和 artifactId,并使用其声明的 version 和 scope。
<dependencies>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
dependency>
dependencies>
允许子模块声明 version 和 scope, 来覆盖父级继承的配置。
<dependencies>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
<version>3.18version>
dependency>
dependencies>
使用 dependencyManagement 时,如果项目中出现了多个传递依赖的版本,会被 dependencyManagement 声明的版本覆盖。有好处也有坏处。
如果版本兼容的话,就剩了我们去排除版本的麻烦。
缺点是,出现版本冲突的时候,不是很容易被注意到。
父 pom 中的 dependencyManagement 是允许被子模块的 dependencyManagement 覆盖的。
沿着树向上层 pom 查找最近的 dependencyManagement 声明的 groupId 和 artifactId。这也就说明了如果子类 dependencyManagement 声明了与父 dependencyManagement 相同的 groupId 和 artifactId,则以最近的为准。如果层次相同,则先声明的优先级更高。
因此,结合 dependencies 来看:
1.dependencies 优先级高于 dependencyManagement。
2.在依赖树上,离引入位置越近的层次,则优先级越高。
3.层次相同,则先声明的优先级更高。