领先一步
VMware 提供培训和认证,以加速您的进步。
了解更多Maven 的 依赖管理 包括物料清单 (BOM) 的概念。BOM 是一种特殊的 POM,用于控制项目依赖项的版本,并提供一个中心位置来定义和更新这些版本。
许多 Spring 项目(包括 Spring Framework、Spring Cloud、Spring Boot 和 Spring IO Platform)都提供了 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 的启动器 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 也用于 问题跟踪。我们始终欢迎功能建议、拉取请求和错误报告。