Spring Framework 5 中的新特性

https://www.ibm.com/developerworks/cn/java/j-whats-new-in-spring-framework-5-theedom/index.html

Spring 5 于 2017 年 9 月發布了通用版本 (GA),它標志著自 2013 年 12 月以來第一個主要 Spring Framework 版本。它提供了一些人們期待已久的改進,還采用了一種全新的編程范例,以反應式宣言中陳述的反應式原則為基礎。

這個版本是很長時間以來最令人興奮的 Spring Framework 版本。Spring 5 兼容 Java?8 和 JDK 9,它集成了反應式流,以便提供一種顛覆性方法來實現端點和 Web 應用程序開發。

誠然,反應式編程不僅是此版本的主題,還是令許多開發人員激動不已的重大特性。人們對能夠針對負載波動進行無縫擴展的災備和響應式服務的需求在不斷增加,Spring 5 很好地滿足了這一需求。

本文將全面介紹 Spring 5。我將介紹 Java SE 8 和 Java EE 7 API 的基準升級、Spring 5 的新反應式編程模型、HTTP/2?支持,以及 Spring 通過 Kotlin 對函數式編程的全面支持。我還會簡要介紹測試和性能增強,最后介紹對 Spring 核心和容器的一般性修訂。

升級到 Java SE 8 和 Java EE 7

直到現在,Spring Framework 仍支持一些棄用的 Java 版本,但 Spring 5 已從舊包袱中解放出來。為了充分利用 Java 8 特性,它的代碼庫已進行了改進,而且該框架要求將 Java 8 作為最低的 JDK 版本。

Spring 5 在類路徑(和模塊路徑)上完全兼容 Java 9,而且它通過了 JDK 9 測試套件的測試。對 Java 9 愛好者而言,這是一條好消息,因為在 Java 9 發布后,Spring 能立即使用它。

在 API 級別上,Spring 5 兼容 Java EE 8 技術,滿足對 Servlet 4.0、Bean Validation 2.0 和全新的 JSON Binding API 的需求。對 Java EE API 的最低要求為 V7,該版本引入了針對 Servlet、JPA 和 Bean Validation API 的次要版本。

反應式編程模型

Spring 5 最令人興奮的新特性是它的反應式編程模型。Spring 5 Framework 基于一種反應式基礎而構建,而且是完全異步和非阻塞的。只需少量的線程,新的事件循環執行模型就可以垂直擴展。

該框架采用反應式流來提供在反應式組件中傳播負壓的機制。負壓是一個確保來自多個生產者的數據不會讓使用者不堪重負的概念。

Spring WebFlux 是 Spring 5 的反應式核心,它為開發人員提供了兩種為 Spring Web 編程而設計的編程模型:一種基于注解的模型和 Functional Web Framework (WebFlux.fn)。

基于注解的模型是 Spring WebMVC 的現代替代方案,該模型基于反應式基礎而構建,而 Functional Web Framework 是基于@Controller?注解的編程模型的替代方案。這些模型都通過同一種反應式基礎來運行,后者調整非阻塞 HTTP 來適應反應式流 API。

使用注解進行編程

WebMVC 程序員應該對 Spring 5 的基于注解的編程模型非常熟悉。Spring 5 調整了 WebMVC 的?@Controller?編程模型,采用了相同的注解。

在清單 1 中,BookController?類提供了兩個方法,分別響應針對某個圖書列表的 HTTP 請求,以及針對具有給定?id?的圖書的 HTTP 請求。請注意 resource 方法返回的對象(Mono?和?Flux)。這些對象是實現反應式流規范中的?Publisher?接口的反應式類型。它們的職責是處理數據流。Mono?對象處理一個僅含 1 個元素的流,而 Flux 表示一個包含 N 個元素的流。

清單 1. 反應式控制器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RestController
public class BookController {
????@GetMapping("/book")
????Flux<Book> list() {
????????return this.repository.findAll();
????}
????@GetMapping("/book/{id}")
????Mono<Book> findById(@PathVariable String id) {
????????return this.repository.findOne(id);
????}
????// Plumbing code omitted for brevity
}

這是針對 Spring Web 編程的注解。現在我們使用函數式 Web 框架來解決同一個問題。

函數式編程

Spring 5 的新函數式方法將請求委托給處理函數,這些函數接受一個服務器請求實例并返回一種反應式類型。清單 2 演示了這一過程,其中?listBook?和?getBook?方法類似于清單 1 中的功能。

清單 2. 清單 2.BookHandler 函數類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class BookHandler {
????public Mono<ServerResponse> listBooks(ServerRequest request) {
????????return ServerResponse.ok()
????????????.contentType(APPLICATION_JSON)
????????????.body(repository.allPeople(), Book.class);
????}
?????
????public Mono<ServerResponse> getBook(ServerRequest request) {
????????return repository.getBook(request.pathVariable("id"))
????????????.then(book -> ServerResponse.ok()
????????????.contentType(APPLICATION_JSON)
????????????.body(fromObject(book)))
????????????.otherwiseIfEmpty(ServerResponse.notFound().build());
????}
????// Plumbing code omitted for brevity
}

通過路由函數來匹配 HTTP 請求謂詞與媒體類型,將客戶端請求路由到處理函數。清單 3 展示了圖書資源端點 URI 將調用委托給合適的處理函數:

清單 3. Router 函數
1
2
3
4
5
6
7
8
9
BookHandler handler = new BookHandler();
RouterFunction<ServerResponse> personRoute =
????route(
????????GET("/books/{id}")
????????.and(accept(APPLICATION_JSON)), handler::getBook)
????????.andRoute(
????GET("/books")
????????.and(accept(APPLICATION_JSON)), handler::listBooks);

這些示例背后的數據存儲庫也支持完整的反應式體驗,該體驗是通過 Spring Data 對反應式 Couchbase、Reactive MongoDB 和 Cassandra 的支持來實現的。

使用 REST 端點執行反應式編程

新的編程模型脫離了傳統的 Spring WebMVC 模型,引入了一些很不錯的新特性。

舉例來說,WebFlux 模塊為?RestTemplate?提供了一種完全非阻塞、反應式的替代方案,名為?WebClient。清單 4 創建了一個?WebClient,并調用?books?端點來請求一本給定?id?為?1234?的圖書。

清單 4. 通過 WebClient 調用 REST 端點
1
2
3
4
5
6
Mono<Book> book = WebClient.create("http://localhost:8080")
??????.get()
??????.url("/books/{id}", 1234)
??????.accept(APPLICATION_JSON)
??????.exchange(request)
??????.then(response -> response.bodyToMono(Book.class));

HTTP/2 支持

Spring Framework 5.0 將提供專門的?HTTP/2 特性支持,還支持人們期望出現在 JDK 9 中的新 HTTP 客戶端。盡管 HTTP/2 的服務器推送功能已通過 Jetty servlet 引擎的?ServerPushFilter?類向 Spring 開發人員公開了很長一段時間,但如果發現 Spring 5 中開箱即用地提供了?HTTP/2?性能增強,Web 優化者們一定會為此歡呼雀躍。

Java EE Servlet 規范預計將于 2017 年第 4 季度發布,Servlet 4.0 支持將在 Spring 5.1 中提供。到那時,HTTP/2 特性將由 Tomcat 9.0、Jetty 9.3 和 Undertow 1.4 原生提供。

Kotlin 和 Spring WebFlux

Kotlin 是一種來自?JetBrains?的面向對象的語言,它支持函數式編程。它的主要優勢之一是與 Java 有非常高的互操作性。通過引入對 Kotlin 的專門支持,Spring 在 V5 中全面吸納了這一優勢。它的函數式編程風格與 Spring WebFlux 模塊完美匹配,它的新路由 DSL 利用了函數式 Web 框架以及干凈且符合語言習慣的代碼。可以像清單 5 中這樣簡單地表達端點路由:

清單 5. Kotlin 的用于定義端點的路由 DSL
1
2
3
4
5
6
7
8
9
10
11
12
13
@Bean
fun apiRouter() = router {
????(accept(APPLICATION_JSON) and "/api").nest {
????????"/book".nest {
????????????GET("/", bookHandler::findAll)
????????????GET("/{id}", bookHandler::findOne)
????????}
????????"/video".nest {
????????????GET("/", videoHandler::findAll)
????????????GET("/{genre}", videoHandler::findByGenre)
????????}
????}
}

使用 Kotlin 1.1.4+ 時,還添加了對 Kotlin 的不可變類的支持(通過帶默認值的可選參數),以及對完全支持 null 的 API 的支持。

使用 Lambda 表達式注冊 bean

作為傳統 XML 和 JavaConfig 的替代方案,現在可以使用 lambda 表達式注冊 Spring bean,使 bean 可以實際注冊為提供者。清單 6 使用 lambda 表達式注冊了一個?Book?bean。

清單 6. 將 Bean 注冊為提供者
1
2
3
4
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean(Book.class, () -> new
??????????????Book(context.getBean(Author.class))
????????);

Spring WebMVC 支持最新的 API

全新的 WebFlux 模塊提供了許多新的、令人興奮的功能,但 Spring 5 也迎合了愿意繼續使用 Spring MVC 的開發人員的需求。Spring 5 中更新了模型-視圖-控制器框架,以兼容 WebFlux 和最新版的?Jackson 2.9?和?Protobuf 3.0,甚至包括對新的?Java EE 8 JSON-Binding API?的支持。

除了?HTTP/2 特性的基礎服務器實現之外,Spring WebMVC 還通過 MVC 控制器方法的一個參數來支持 Servlet 4.0 的?PushBuilder。最后,WebMVC 全面支持 Reactor 3.1 的?Flux?和?Mono?對象,以及?RxJava?1.3 和 2.1,它們被視為來自 MVC 控制器方法的返回值。這項支持的最終目的是支持 Spring Data 中的新的反應式 WebClient 和反應式存儲庫。

使用 JUnit 5 執行條件和并發測試

Spring 5 的測試套件通過多種方式得到了增強,但最明顯的是它對?JUnit 5?的支持。現在可以在您的單元測試中利用 Java 8 中提供的函數式編程特性。清單 7 演示了這一支持:

清單 7. 清單 7.JUnit 5 全面接納了 Java 8 流和 lambda 表達式
1
2
3
4
5
6
7
@Test
void givenStreamOfInts_SumShouldBeMoreThanFive() {
????assertTrue(Stream.of(20, 40, 50)
??????.stream()
??????.mapToInt(i -> i)
??????.sum() > 110, () -> "Total should be more than 100");
}

Spring 5 繼承了?JUnit 5?在 Spring TestContext Framework 內實現多個擴展 API 的靈活性。舉例而言,開發人員可以使用 JUnit 5 的條件測試執行注解?@EnabledIf?和?@DisabledIf?來自動計算一個?SpEL?(Spring Expression Language) 表達式,并適當地啟用或禁用測試。借助這些注解,Spring 5 支持以前很難實現的復雜的條件測試方案。Spring TextContext Framework 現在能夠并發執行測試。

使用 Spring WebFlux 執行集成測試

Spring Test 現在包含一個?WebTestClient,后者支持對 Spring WebFlux 服務器端點執行集成測試。WebTestClient?使用模擬請求和響應來避免耗盡服務器資源,并能直接綁定到 WebFlux 服務器基礎架構。

WebTestClient?可綁定到真實的服務器,或者使用控制器或函數。在清單 8 中,WebTestClient?被綁定到 localhost:

清單 8. 綁定到 localhost 的?WebTestClient
1
2
3
4
WebTestClient testClient = WebTestClient
??.bindToServer()
??.baseUrl("http://localhost:8080")
??.build();

在清單 9 中,測試了?RouterFunction

清單 9. 將?WebTestClient?綁定到?RouterFunction
1
2
3
4
5
6
7
8
9
10
11
RouterFunction bookRouter = RouterFunctions.route(
??RequestPredicates.GET("/books"),
??request -> ServerResponse.ok().build()
);
??
WebTestClient
??.bindToRouterFunction(bookRouter)
??.build().get().uri("/books")
??.exchange()
??.expectStatus().isOk()
??.expectBody().isEmpty();

包清理和棄用

Spring 5 中止了對一些過時 API 的支持。遭此厄運的還有 Hibernate 3 和 4,為了支持 Hibernate 5,它們遭到了棄用。另外,對 Portlet、Velocity、JasperReports、XMLBeans、JDO 和 Guava 的支持也已中止。

包級別上的清理工作仍在繼續:Spring 5 不再支持?beans.factory.accessjdbc.support.nativejdbcmock.staticmock(來自 spring-aspects 模塊)或?web.view.tiles2M。Tiles 3 現在是 Spring 的最低要求。

對 Spring 核心和容器的一般更新

Spring Framework 5 改進了掃描和識別組件的方法,使大型項目的性能得到提升。目前,掃描是在編譯時執行的,而且向?META-INF/spring.components?文件中的索引文件添加了組件坐標。該索引是通過一個為項目定義的特定于平臺的應用程序構建任務來生成的。

標有來自?javax 包的注解的組件會添加到索引中,任何帶?@Index?注解的類或接口都會添加到索引中。Spring 的傳統類路徑掃描方式沒有刪除,而是保留為一種后備選擇。有許多針對大型代碼庫的明顯性能優勢,而托管許多 Spring 項目的服務器也會縮短啟動時間。

Spring 5 還添加了對?@Nullable?的支持,后者可用于指示可選的注入點。使用者現在必須準備接受 null 值。此外,還可以使用此注解來標記可以為 null 的參數、字段和返回值。@Nullable?主要用于 IntelliJ IDEA 等 IDE,但也可用于 Eclipse 和 FindBugs,它使得在編譯時處理 null 值變得更方便,而無需在運行時發送?NullPointerExceptions

Spring Logging 還提升了性能,自帶開箱即用的 Commons Logging 橋接器。現在已通過資源抽象支持防御性編程,為?getFile訪問提供了?isFile?指示器。

結束語

Spring 5 的首要特性是新的反應式編程模型,這代表著對提供可無縫擴展、基于 Spring 的響應式服務的重大保障。隨著人們對 Spring 5 的采用,開發人員有望看到反應式編程將會成為使用 Java 語言的 Web 和企業應用程序開發的未來發展道路。

未來的 Spring Framework 版本將繼續反映這一承諾,因為 Spring Security、Spring Data 和 Spring Integration 有望采用反應式編程的特征和優勢。

總之,Spring 5 代表著一次大受 Spring 開發人員歡迎的范例轉變,同時也為其他框架指出了一條發展之路。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/538852.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/538852.shtml
英文地址,請注明出處:http://en.pswp.cn/news/538852.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

怎么計算一組數據的波動_稅控盤數據和小規模增值稅申報表計算結果不一致怎么辦...

a公司為小規模納稅人&#xff0c;于2020年1月申報2019年第四季度增值稅時&#xff0c;是按照金稅盤的數據實際銷售金額為562,563,13元&#xff0c;實際銷售稅額為16,876.87元填寫小規模納稅人增值稅申報表。申報成功后&#xff0c;稅務系統卻跳出比對異常&#xff0c;戶管員要求…

簡單又好看的按鈕,扁平化按鈕。

原文地址&#xff1a;http://blog.csdn.net/peijiangping1989/article/details/19333779 點擊閱讀原文 ----------------------------------------------------------- 今天分享一下流行的扁平化按鈕。完全不需要用到圖片哦。效果圖如下&#xff1a; 里面有2個按鈕都是一樣的…

python輸入三行、能出來三行數據_python 讀入多行數據的實例

一、前言本文主要使用python 的raw_input() 函數讀入多行不定長的數據&#xff0c;輸入結束的標志就是不輸入數字情況下直接回車&#xff0c;并填充特定的數作為二維矩陣二、代碼def get2dlistdata():res []inputline raw_input() #以字符串的形式讀入一行#如果不為空字符串作…

請問,現在android流行什么開源框架?

retrofit2.0RxjavagreenDao3大流行圖片庫p,g,f&#xff08;Picasso&#xff0c;Fresco&#xff0c;Glide&#xff09; 3分鐘全面了解Android主流圖片加載庫 http://blog.csdn.net/carson_ho/article/details/51939774 Retrofit2使用&#xff08;非常簡潔易懂&#xff09; ht…

matlab 銳化降噪,matlab 圖形銳化 濾波

help imreadhelp fspecial imfilt幫助穩定中有較多的示例fspecial 函數功能&#xff1a;產生預定義濾波器格式&#xff1a;Hfspecial(type)Hfspecial(gaussian,n,sigma) 高斯低通濾波器Hfspecial(sobel) Sobel 水平邊緣增強濾波器Hfspecial…

執行 link.exe 時出錯_在20多歲時應該做什么,以避免在30多歲和40多歲時后悔?...

1. 永遠不要以為自己可以&#xff0c;將會或曾經到達過以為是錯誤的。無論是幸福&#xff0c;收入還是心態。在二十多歲的關鍵時期&#xff0c;我有這種心態&#xff0c;對我自己不利。認為自己“實現”是一種靜態的世界觀&#xff0c;阻礙了您的成長。接受這樣的事實&#xff…

音頻自動增益 與 靜音檢測 算法 附完整C代碼

前面分享過一個算法《音頻增益響度分析 ReplayGain 附完整C代碼示例》 主要用于評估一定長度音頻的音量強度&#xff0c; 而分析之后&#xff0c;很多類似的需求&#xff0c;肯定是做音頻增益&#xff0c;提高音量諸如此類做法。 不過在項目實測的時候&#xff0c;其實真的很難…

python繪制餅狀圖圖例_使用matplotlib的所有餅圖的通用圖例

圖例只需調用一次&#xff0c;否則將顯示7個不同的圖例。我在下面展示了一個例子。請注意&#xff0c;您必須將自己的數據替換為ax.pie()&#xff1a;data1 (10,90) # some data to be plotted data2 (40,50) data3 (70,30) labels [Sending Data, Not Sending Data] #lege…

Android初始化本地數據庫

原文&#xff1a;http://blog.csdn.net/itjavawfc/article/details/50860647 點擊閱讀原文 -------------------------------- 最近遇到一個需求&#xff0c;一個同學不會搭服務器&#xff0c;但是Android課程設計需要用到很多數據&#xff0c;這樣就出現了一個問題&#xff0c…

jsp springmvc 視圖解析器_springMVC配置jsp/html視圖解析器

1、maven項目引入freemark相關jar包freemaker是以個模板引擎&#xff0c;可以根據提供的數據和創建好的模板,去自動的創建html靜態頁面。所以在返回html視圖時可以用這個引擎結合數據生成html靜態頁面。org.springframeworkspring-context-support5.0.7.RELEASEorg.freemarkerf…

php設計模式原型模式,原型模式_設計模式_設計模式之原型模式 - Lane Blog

108Clicks: 6614 Date: 2014-04-21 21:48:35 Power By 李軒Lane原型模式提取重復功能&#xff0c;避免了程序員喜歡復制粘貼的壞習慣。設計模式中的原型模式就是&#xff0c;用原型實例指定創建對象的重力&#xff0c;通過拷貝這些原型來創建新的對象從一個對象再創建另外一個可…

Windows2003如何安裝IIS和ftp

【開始】----【控制面板】----【添加或刪除程序】 出現如下“添加或刪除程序”界面&#xff0c;點擊“添加/刪除windows組件&#xff08;a&#xff09; ” 出現如下“window組件向導”界面 下拉“組件”欄目條&#xff0c;選擇“應用程序服務器” 點擊“應用程序服務器”下的“…

hadoop臨時文件 jar包_hadoop之Mapper/reducer源碼分析之二

若當前JobClient (0.22 hadoop) 運行在YARN.則job提交任務運行在YARNRunnerHadoop Yarn 框架原理及運作機制主要步驟作業提交作業初始化資源申請與任務分配任務執行具體步驟在運行作業之前&#xff0c;Resource Manager和Node Manager都已經啟動&#xff0c;所以在上圖中&#…

ANDROID:SHOWASACTION="NEVER"是做什么用的?

原文地址&#xff1a;http://www.cnblogs.com/android-joker/p/4478491.html 點擊閱讀原文 --------------------------------------------------------- 安卓開發項目文件中有一個目錄叫做menu&#xff0c;里面有tybmain.xml item選項里有一句 android:showAsAction "…

吳恩達ex3_Wu-Enda機器學習編程作業Python實現EX3,吳恩達,machinelearning,python,ex3nn

# -*- coding: utf-8 -*-"""Created on Wed Jul 1 20:28:57 2020author: cheetah023"""import numpy as npimport matplotlib.pyplot as pltimport scipy.io as sciimport random as ra#函數定義def sigmoid(X):return 1 /(1 np.exp(-X))def pr…

php數組驗證用戶名密碼,求個php數組驗證問題,在線等

現在有這么一個數組,是屬性表Array([0] > Array([list_attr_id] > 30[list_attr_name] > 顏色[list_attr_attr] > 黑色|白色|金色[list_attr_price] > 0|10.1|20[list_attr_shop_id] > 28)[1] > Array([list_attr_id] > 31[list_attr_name] > 規格[…

基于python的視頻監控系統_Python實現微信監控報警系統

概述: 本文主要分享一下博主在學習wxpy 的過程中開發的一個小程序。博主在最近有一個監控報警的需求需要完成&#xff0c;然后剛好在學習wxpy 這個東西&#xff0c;因此很巧妙的將工作和學習聯系在一起。 博文中主要使用到的技術設計到Python&#xff0c;Redis&#xff0c;以及…

python 編碼文件json.loads json.dumps

python 編碼文件json.loads json.dumps import yaml d {name: 張三, age: 1} print d jd json.dumps(d, ensure_asciiFalse, encodingutf-8)) ud json.loads(jd, encodingutf-8) print ud ud yaml.safe_load(jd, encodingutf-8) print udposted on 2018-04-23 15:18 秦瑞It…

getActionBar()報空指針異常

調用 getActionBar()的Activity類 public class WlanListActivity extends AppCompatActivity 在使用getActionBar("標題內容")的時候報空指針。 原因是要用AppCompatActivity類里的getSupportActionBar()

python 類中定義列表_Python3中的自定義列表類,具有

我想用python3編寫一個自定義列表類&#xff0c;就像在這個問題How would I create a custom list class in python?中一樣&#xff0c;但與該問題不同&#xff0c;我想實現__get__和{}方法。雖然我的類與list類似&#xff0c;但是這些方法背后隱藏著一些神奇的操作。所以我想…