领先一步
VMware 提供培训和认证,为你的进步加速。
了解更多Maven 的依赖管理包含物料清单 (bom) 的概念。bom 是一种特殊的 pom,用于控制项目依赖项的版本,并提供一个中心位置来定义和更新这些版本。
包括 Spring Framework、Spring Cloud、Spring Boot 和 Spring IO Platform 在内的许多 Spring 项目都提供了 bom,以便 Maven 用户更容易使用。遗憾的是,如果你使用的是 Gradle,事情就没有那么容易了。
Gradle 的依赖管理使用一个 ResolutionStrategy
来控制项目的依赖版本。这提供了很大的能力和灵活性,但没有提供一种重用 Maven bom 中已声明的依赖管理的方法。因此,你必须手动进行配置。根据 bom 的不同,这很容易导致你的 build.gradle
脚本中增加数十行代码,仅仅是为了重用一些现有配置。
Gradle 的主要优势之一是可以通过使用插件轻松扩展和定制其行为。我们利用了这一点,并为 Gradle 编写了一个依赖管理插件。它兼容 Gradle 1.x 和 2.x。这个插件允许你用几行代码使用 Maven bom 来控制构建的依赖项。第一步是应用插件
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "io.spring.gradle:dependency-management-plugin:0.5.1.RELEASE"
}
}
apply plugin: "io.spring.dependency-management"
应用插件后,你可以使用它导入 Maven bom
dependencyManagement {
imports {
mavenBom 'io.spring.platform:platform-bom:1.1.1.RELEASE'
}
}
有了这个配置,你就可以声明对 bom 中任何依赖项的依赖,而无需指定版本
dependencies {
compile 'org.springframework:spring-core'
}
导入的 bom 将控制依赖项的版本。如果传递性依赖项在 bom 中列出,它也将控制其版本。
Gradle 可以从 Maven 仓库检索依赖项,并使用 Maven pom 文件中的元数据进行操作。然而,它并非遵守 Maven 的规则,而是对元数据应用了自己微妙不同的语义。其中一个可能导致问题的地方是传递性依赖项的排除。一个简单的例子可以最好地说明这一点。
想象一个模块依赖于几个 Spring Framework 模块,spring-core
和 spring-beans
,并且使用 SLF4J 而不是 Commons Logging。其 pom 中的依赖项可能看起来像这样
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.1.4.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.10</version>
</dependency>
如果一个 Maven 构建依赖于这个模块,它的依赖树将看起来像这样
\- com.example:my-library:jar:0.0.1-SNAPSHOT:compile
+- org.springframework:spring-core:jar:4.1.4.RELEASE:compile
+- org.springframework:spring-beans:jar:4.1.4.RELEASE:compile
\- org.slf4j:jcl-over-slf4j:jar:1.7.10:compile
\- org.slf4j:slf4j-api:jar:1.7.10:compile
commons-logging
没有被列出,因为唯一依赖它的模块是 spring-core
,并且它已经被排除。
等效的 Gradle 构建的依赖树看起来像这样
\--- com.example:my-library:0.0.1-SNAPSHOT
+--- org.springframework:spring-core:4.1.4.RELEASE
| \--- commons-logging:commons-logging:1.2
+--- org.springframework:spring-beans:4.1.4.RELEASE
| \--- org.springframework:spring-core:4.1.4.RELEASE (*)
\--- org.slf4j:jcl-over-slf4j:1.7.10
\--- org.slf4j:slf4j-api:1.7.10
尽管进行了排除,这次 commons-logging
仍然被列出。这可能会有问题,因为它会使你的类路径充斥着本不应该存在的依赖项。你可以通过在 Gradle 构建中手动配置所需的排除来解决此问题,但首先你必须知道应该排除哪些依赖项,然后你必须经历繁琐且容易出错的配置过程。
依赖管理插件改变了 Gradle 对 pom 排除规则的处理方式,使其行为与 Maven 中一致。将该插件应用于示例项目后,它不再引入 commons-logging
\--- com.example:my-library:0.0.1-SNAPSHOT
+--- org.springframework:spring-core:4.1.4.RELEASE
+--- org.springframework:spring-beans:4.1.4.RELEASE
| \--- org.springframework:spring-core:4.1.4.RELEASE
\--- org.slf4j:jcl-over-slf4j:1.7.10
\--- org.slf4j:slf4j-api:1.7.10
此插件与 Spring Boot 的 Gradle 插件有一些相似之处。例如,Spring Boot 插件也允许声明不带版本的依赖项,但它不影响传递性依赖项,也不遵守 Maven 的排除规则。
在即将发布的 Spring Boot 1.3 中,我们移除了 Boot 自己的依赖管理,转而开始使用依赖管理插件。对于使用早期版本 Spring Boot 的用户,这两个插件可以很好地共存,你可以配置依赖管理插件来使用 Spring Boot 的 starter bom
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "io.spring.gradle:dependency-management-plugin:0.5.1.RELEASE"
classpath "org.springframework.boot:spring-boot-gradle-plugin:1.2.3.RELEASE"
}
}
apply plugin: "io.spring.dependency-management"
apply plugin: "spring-boot"
repositories {
jcenter()
}
dependencyManagement {
imports {
mavenBom 'org.springframework.boot:spring-boot-starter-parent:1.2.1.RELEASE'
}
}
dependencies {
compile "org.springframework.boot:spring-boot-starter-web"
}
除了上述功能外,该插件还支持使用 bom 的属性(包括覆盖它们并在你的 Gradle 构建中使用它们),自动在 Gradle 生成的 pom 文件中包含依赖管理元数据等等。请查看 README 获取更多详细信息。
该插件采用 Apache 许可,并在 GitHub 上可用。GitHub 也用于问题跟踪。功能建议、拉取请求和错误报告随时欢迎。