领先一步
VMware提供培训和认证,以加快您的进步。
了解更多在Brixton发布列车中的Spring Cloud中,现在可以使用Spring Boot 1.3中的一些有趣的新功能。 Spring Cloud的Angel发布列车与Spring Boot 1.3部分不兼容,因此升级时需要注意一些重要事项。本文将帮助您了解这些更改,并更新任何现有应用程序以使用新功能。在尝试将Spring项目的新版本应用到现有代码库时,它通常也很有用。
提示:您可以使用
mvn dependency:tree
或gradle dependencies
列出项目中的依赖项并检查版本。
如果您使用的是旧版本的 Spring Boot,您的 Maven POM 中可能包含以下内容
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.7.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
或者
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.7.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
或者,如果您使用的是 Gradle,
buildscript {
ext {
springBootVersion = '1.2.7.RELEASE'
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
要升级到 Spring Boot 1.3.0,您需要将上面的“1.2.7”更改为“1.3.0”。到目前为止,非常简单。
提示:要查看包含最新版本 Spring Boot 的“典型”Maven POM,您可以使用
curl start.spring.io/pom.xml
。要添加 Spring Cloud,您可以附加-d style=cloud-config-client
。可以通过添加-d bootVersion=1.3.1.BUILD-SNAPSHOT
(例如)来更改 Spring Boot 版本。对于 Gradle,请使用build.gradle
代替pom.xml
。
由于 Spring Cloud 基于 Spring Boot 之上,因此找到可以一起工作的组合可能会令人困惑和困难。在下文中,我们将描述几种升级方案,并展示您可以通过依赖项管理实现的目标。
通常,最大的变化发生在您升级时(Spring Boot 1.2 到 1.3,或 Spring Cloud Angel 到 Brixton)。如果您从Spring Initializr下载了一个项目,那么它将使用 Spring Boot 父 POM
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
以及<dependencyManagement>
部分中的 Spring Cloud BOM
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Angel.SR4</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在 Gradle 中,您将看到类似的内容
buildscript {
ext {
springBootVersion = '1.2.7.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-starter-parent:Angel.SR4"
}
}
仅仅更新 Spring Boot 版本在任何情况下都不会奏效,因为 Spring Cloud Angel BOM 具有旧版本的 Spring Boot 和 Spring(以及其他内容)。因此,我们确实需要同时升级 Spring Boot 和 Spring Cloud。例如,在 Maven 中
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Brixton.M3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在 Gradle 中
buildscript {
ext {
springBootVersion = '1.3.0.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-starter-parent:Brixton.M3"
}
}
注意:Spring Cloud 的 Brixton.M2 和所有早期版本都与 Spring Boot 1.3.0.RELEASE *不*兼容。您至少需要 Brixton.M3。
假设您想使用 Spring Boot 快照,或者在发布时升级到 1.3.1,但是 Spring Cloud 没有明确依赖于您所需 Boot 版本的版本。
在 Maven 中,请记住,如果您使用的是现成的父 POM,则它们包含<dependencyManagement>
并将优先。考虑到这一点,如果您使用这些父 POM,请务必使用与您所需依赖项集最接近的父 POM(此场景中的 Boot POM)。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.1.BUILD-SNAPSHOT</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Brixton.M3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
从原则上讲,Gradle 中的情况更简单,因为它没有“父”的概念。实际上,除非您也手动应用依赖管理插件,否则 Spring Boot 插件无法与依赖管理不同的版本一起应用。因此,您必须在build.gradle
中进行一些操作。
buildscript {
ext {
springBootVersion = '1.3.0.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath "io.spring.gradle:dependency-management-plugin:0.5.3.RELEASE"
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: "io.spring.dependency-management"
...
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-starter-parent:Brixton.M3"
mavenBom "org.springframework.bootspring-boot-starter-parent:1.3.1.BUILD-SNAPSHOT"
}
}
apply plugin: 'spring-boot'
规则是,您必须 a) 手动导入依赖管理插件并在 Spring Boot 插件 *之前* 导入,b) 在应用 Spring Boot 插件 *之前* 声明dependencyManagement
。完成此操作后,您可以列出dependencyManagement
声明中的依赖项,并且*最后一个*获胜(与 Maven 相反)。
注意:这种对声明顺序的敏感性是当前版本工具的“特性”。在将来的版本中,情况可能会有所不同。有关更多详细信息,请参阅Gradle 工具中的此问题。
如果您不使用现成的父 POM,则可以自由使用 *不* 包含<dependencyManagement>
的父 POM,这使得控制更加容易。在这种情况下,您需要将 Spring Boot 和 Spring Cloud 都放入<dependencyManagement>
中,并且顺序很重要:第一个获胜(Gradle 的最后一个)。例如,要在 Maven 中使用 Spring Boot 1.3.1.BUILD-SNAPSHOT 和 Spring Cloud Brixton.M3
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.1.BUILD-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Brixton.M3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
请注意,在 Maven 和 Gradle 中,BOM 的顺序都很重要:如果在顶级(显式声明的依赖项)存在冲突,则首先声明的 BOM 通常在 Maven 中获胜(Gradle 中的最后一个)。Maven 的一个重大区别在于父级是特殊的:如果它包含<dependencyManagement>
,它总是获胜。
理解特定依赖项版本是否会以您需要的方式解析非常复杂。它取决于 BOM 的顺序,*以及*您的依赖项声明在传递依赖树中的深度。例如,Spring Boot BOM 为spring-core
声明了显式(级别 1)依赖管理,但没有为任何其他 Spring Framework jar 声明(这些 jar 通过对 Spring Framework BOM 的引用引入)。规则是第一次声明获胜,但整个树都包含在内(包括所有 BOM),从上到下逐层搜索。
注意:如果没有 Spring Boot(或 Spring 依赖管理)插件,Gradle 没有这个“最后一个获胜”规则。要使用“原生”Gradle 构建执行相同的操作,通常需要仔细且费力的工作来手动修复传递依赖项版本。
如果您想将依赖项的版本提升到 Spring Boot 和 Spring Cloud BOM 中指定的版本之外,事情可能会变得复杂。总的来说,有两种选择:属性和附加 BOM。第一个(属性)适用于现成的父 POM,而另一个则不适用。第二个(更多 BOM)仅在您感兴趣的依赖项存在 BOM 时才有效,并且仅当传递依赖项不与您的要求冲突时才有效。例如,所有 Spring Cloud 项目都有自己的 BOM,Spring Framework 也是如此,这是一个开始。
Spring Boot 父 POM(如果您使用它,则 Spring Cloud POM 也一样,因为它继承自 Boot POM)将其所有依赖项版本提取到<properties/>
中。因此,您通常只需更改属性值即可。Maven 中的示例
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<spring.version>4.2.4.BUILD-SNAPSHOT</spring.version>
</properties>
Gradle 中相应的特性是ext
属性,例如:
ext['spring.version'] = '4.2.4.BUILD-SNAPSHOT'
Spring框架有自己的BOM,因此我们可以用它来管理Spring版本,而不是在Maven中使用自定义父POM(不包含`<dependencyManagement>`)。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>4.2.4.BUILD-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
注意:此示例实际上**不能**与Spring Boot父POM一起使用(除非它恰好具有相同的`<spring.version/>`),因为Spring框架版本已由父POM固定。要将Spring Boot父POM与Spring框架快照一起使用,最好使用属性方法(如上所述)。
在Gradle中更简单(因为没有父POM来设置冲突的版本)。
dependencyManagement {
imports {
mavenBom "org.springframework:spring-framework-bom:4.2.4.BUILD-SNAPSHOT"
mavenBom "org.springframework.boot:spring-boot-starter-parent:1.3.0.RELEASE"
}
}
依赖管理很困难,但希望我们通过概述升级Spring Boot和Spring Cloud的几个常见场景来缓解这个问题。根据您选择Maven还是Gradle,有一些略微不同的行为,但至少如果您选择Gradle并使用Spring Boot插件,差异将最小化。最终,Spring项目有不同的发布计划,因此始终可能存在冲突,但它们通常总是朝着融合方向发展,因此如果您等待足够长的时间,事情就会平衡。像Spring Cloud、Spring Boot和Spring IO Platform这样的伞形项目也有助于消除障碍:如果您能使用其中一个来管理所有依赖项,事情就会变得简单得多。
Spring指南中的示例应用程序现已全部更新到Spring Boot 1.3,即使这意味着它们依赖于Spring Cloud的里程碑版本(这仅适用于Zuul代理示例)。许多不再需要Spring Cloud。如果您需要Spring Cloud的GA版本,目前您需要保留Spring Boot 1.2。该组合的示例可以从git历史记录中提取。