笔者第三个Spring Cloud(版本为Spring Boot 1.2)类项目升级最新版本时遇到很多问题,本文内容是做者翻译Spring Cloud官网一位国外友人文章产生。git
原文地址:github
做者:DAVE SYERspring
Spring Boot 1.3中有一些有趣的新功能,如今能够在Brixton版本系列的Spring Cloud中使用。Spring Cloud的Angel版本系列与Spring Boot 1.3部分不兼容,所以在升级时须要注意一些重要事项。本文可帮助您更改并更新任何现有应用程序以使用新功能。在尝试将新版本的Spring项目引入现有代码库时,它一般也会有所帮助。app
提示:您可使用
mvn dependency:tree
或gradle dependencies
列出项目中的依赖项并检查版本。框架
若是你使用的是旧版本的Spring Boot,你可能在你的Maven POM中有这样的东西:curl
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.2.7.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent>
要么maven
<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,spring-boot
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
。gradle
因为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>
和部分中的Spring Cloud BOM <dependencyManagement>
:
<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" } }
注意:Brixton.M2和全部早期版本的Spring Cloud 与Spring Boot 1.3.0.RELEASE 不兼容。你至少须要Brixton.M3。
假设您要使用Spring Boot快照,或者在发布时升级到1.3.1,但Spring Cloud没有明确依赖于您想要的Boot版本的版本。
在Maven中,请记住,若是您使用其中包含的现成父POM之一<dependencyManagement>
并将优先使用。考虑到这一点,若是您使用这些父POM,请确保使用具备最接近所需依赖关系的父级(在此方案中为Boot one)。
<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)dependencyManagement
在应用Spring Boot插件以前声明。一旦你这样作,你能够列出dependencyManagement
声明中的依赖项,最后一个获胜(与Maven相反)。
注意:这种对声明顺序的敏感性是当前版本工具的“特征”。在未来的版本中可能会有所不一样。有关详细信息,请参阅Gradle工具中的此问题。
若是您不使用现成的父POM,您能够自由使用不包含的POM <dependencyManagement>
,这使事情更容易控制。在这种状况下,您须要将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的顺序很是重要:若是顶层存在冲突(显式声明的依赖关系),则首先声明的那个一般在Maven中获胜(Gradle中的最后一个)。与Maven的一个重大区别是父母是特殊的:若是它包含<dependencyManagement>
它老是获胜。
要了解特定的依赖版本是否会以您须要的方式解析,这很复杂。它取决于BOM的顺序,以及传递依赖关系树中声明依赖关系的深度。例如,Spring Boot BOM声明了一个显式(级别1)依赖关系管理,spring-core
但没有声明任何其余Spring Framework jar(经过对Spring Framework BOM的引用引入)。规则是第一次声明获胜,可是包括整个树(包括全部BOM),从顶部逐层搜索。
注意:没有Spring Boot(或Spring Dependency Management)插件,Gradle没有这个“最后一个胜利”规则。要使用“本机”Gradle构建作一样的事情,一般须要手动修复传递依赖版本的细致而繁琐的工做。
若是您但愿将依赖项版本超出Spring Boot和Spring Cloud BOM中指定的版本,那么事情就会变得复杂。从广义上讲,有两个选项:属性和其余BOM。第一个(属性)与现成的父POM一块儿工做,而另外一个不工做。第二(更BOM表)只有在有工做是可供你有兴趣,而且仅当传递依赖不符合您的要求相冲突的相关性的BOM。例如,全部Spring Cloud项目都有本身的BOM,就像Spring Framework同样,因此这是一个开始。
Spring Boot父POM(若是您使用它,则使用Spring Cloud,由于它继承自Boot one)将其全部依赖版本提取出来<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 Framework有本身的BOM,所以咱们可使用它来管理Spring版本。在Maven中使用自定义父级(不包含<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框架版本已由父级修复。要将Spring Boot父级与Spring Framwork快照一块儿使用,最好使用属性方法(上面)。
在Gradle中它更简单(由于没有父设置冲突版本):
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这样的Umbrella项目也有助于消除颠簸:若是你可使用其中一个来管理全部依赖项,那么事情会变得更加简单。
Spring指南中的示例应用程序现已所有更新到Spring Boot 1.3,即便这意味着它们依赖于Spring Cloud的里程碑(这仅适用于Zuul代理示例)。许多人再也不须要Spring Cloud了。若是您须要GA版本的Spring Cloud,您须要当即使用Spring Boot 1.2。该组合的样本能够从git历史中解除。