譯自如何將Spring Cloud應用程序從Spring Boot 1.2遷移到1.3

前言

筆者第三個Spring Cloud(版本爲Spring Boot 1.2)類項目升級最新版本時遇到很多問題,本文內容是做者翻譯Spring Cloud官網一位國外友人文章產生。git

原文地址:github

Migrating Spring Cloud Apps from Spring Boot 1.2 to 1.3 

做者:DAVE SYERspring

正文

Spring Boot 1.3中有一些有趣的新功能,如今能夠在Brixton版本系列的Spring Cloud中使用。Spring Cloud的Angel版本系列與Spring Boot 1.3部分不兼容,所以在升級時須要注意一些重要事項。本文可幫助您更改並更新任何現有應用程序以使用新功能。在嘗試將新版本的Spring項目引入現有代碼庫時,它一般也會有所幫助。app

提示:您可使用mvn dependency:treegradle 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.xmlgradle

使用Spring Cloud和Spring Boot

因爲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。

升級超越1.3.0的Spring Boot

假設您要使用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工具中的此問題

將Maven與自定義父級一塊兒使用

若是您不使用現成的父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>

BOM的順序

請注意,在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歷史中解除。

相關文章
相關標籤/搜索