javascript
浅谈Spring5 响应式编程
目錄
- 為什么是響應式編程
- ?用于響應式編程實現的理想案例
- 響應流 (Reactive Streams)
- ?Spring 5 提供的響應式編程
- ?Spring Web Reactive vs. Spring Web MVC
- 響應式編程的基本結構
- Reactive Web Client
- Spring 5 的局限
近年來,響應式編程在開發者社區和客戶中很受歡迎,由于其以聲明的方式構建應用程序的能力,而不是強制,形成更加敏感和有彈性的應用。Spring 5 將反應系統納入其核心框架的事實已經顯示出向聲明式編程的范式轉變。
響應式編程管理數據生產者和消費者之間的異步數據流,它們需要以流暢的方式對數據進行響應。所以,響應式編程都是異步和事件驅動的流暢應用程序,需要少量的線程進行縮放。
響應式編程很難構建基于線程的架構,由于在基于共享可變狀態、線程和鎖的應用程序擴展過程中涉及到高度復雜性。
在響應式編程的上下文中,“在流中有數據時,所有事物都是流并以流暢方式行為。”?
為什么是響應式編程
高層次的抽象與響應式編程導致了代碼可讀性的提高,因此開發人員可以主要關注定義業務邏輯的事件的相互依存性。
在高度并發的環境中,響應模式自然地適合于消息處理,這是一個常見的企業用例。
由于執行反壓力的特性,響應式方法最適合控制生產者和消費者之間的流量,這將有助于避免內存不足。
對于一個或幾個線程,IO綁定任務可以通過異步和非阻塞方式執行,而且不阻塞當前線程。
在高交互和實時應用程序或任何操作/事件時,都可能觸發多個連接子系統的通知,在這種情況下響應式編程可以更有效的進行管理。
?用于響應式編程實現的理想案例
響應流 (Reactive Streams)
“響應流”定義一個 API 規范,其中包含一組最小的接口,這些接口公開了定義非阻塞反壓力的數據流的操作和實體的方法。
隨著反壓力的引入,響應流允許用戶控制來自出版商的數據交換速率。
響應流 API java.util.concurrent.flow 已正式成為 java 9 的一部分。
響應流主要用作互操作層。
?Spring 5 提供的響應式編程
Spring-Web-Reactive 模塊和 Spring MVC 都支持相同的 @Controller 編程,但 Spring-Web-Reactive 是在 Reactive 和非阻塞引擎上執行的。
遵循這個文檔,見:?
http://docs.spring.io/spring-framework/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/web-reactive.html
Spring-Web-Reactive 模塊和 Spring MVC 共享許多通用的算法,但 Spring-Web-Reactive 模塊已經重新定義了許多 Spring MVC 契約,例如 HandlerMapping和HandlerAdapter,以使它們變得異步和非阻塞,以及啟用響應式 HTTP 請求和響應(以 RouterFunction 和 HandlerFunction 的形式)。
除了現有的 RestTemplate 外,新的響應式 WebClient 也在 Spring 5 中引入。
支持響應式編程的 HTTP 客戶端(例如 Reactor、Netty、Undertow)已經采用了一系列響應式的 ClientHttpRequest 和 ClientHttpResponse 抽象,它們將請求和響應體作為 Flux <DataBuffer> 公開,并且在讀寫端提供全面的背壓支持。
Spring 5 Framework 引入了 Reactor,作為 Reactive Streams 規范的實現。
Reactor 是用于在 JVM 上構建非阻塞應用程序的下一代 Reactive 庫。
Reactor 擴展了基本的 Reactive Streams Publisher 契約,并定義了 Flux 和 Mono API 類型,分別為 0..N 和 0..1 的數據序列提供聲明性操作。
Spring Web Reactive 使用 Servlet 3.1 提供了非阻塞 I/O,并運行在 Servlet 3.1 容器上。
Spring WebFlux 提供了兩種編程模型可供選擇。
?Spring Web Reactive vs. Spring Web MVC
Spring 5 包含了 Spring Web Reactive(在 spring-web-reactive 模塊下)和 Spring Web MVC(在 spring-webmvc 模塊下)。
雖然 Spring Web Reactive 和 Spring Web MVC 模塊共享了很多算法,但是由于 Spring Web Reactive 能夠在響應式的非阻塞 Reactive Streams HTTP 適配器層上運行,因此它們之間不共享代碼。
Spring MVC 執行需要 Servlet 容器,而 Spring Web Reactive 也可以在非 Servlet 運行時上運行,比如在 Netty 和 Undertow 上運行。
如果對具有輕量級、函數式的 Web 框架的非阻塞 Web 棧的必要要求,并與 Java 8 lambda 或 Kotlin一起使用,則應該考慮從 Spring MVC 應用程序切換到 Spring Web Reactive。
響應式編程的基本結構
這是一個 2.0.0 M5 版本的? pom.xml ,依賴于 WebFiux。
?| 12345678910 | <parent>?<groupId>org.springframework.boot</groupId>?<artifactId>spring-boot-starter-parent</artifactId>?<version>2.0.0.M5</version></parent><dependencies>?? ?<dependency>??<groupId>org.springframework.boot</groupId>??<artifactId>spring-boot-starter-webflux</artifactId>??????? </dependency></dependencies> |
傳統方法 VS. 響應方法
在傳統方法中,執行將被阻塞,并將一直等到您的服務執行完成為止。在下面的代碼中,在第一個 print 語句之后,程序執行將被阻塞并等待服務執行完成。在服務執行完成后,將恢復程序執行,并執行第二個 print 語句。
?| 1234567 | @GetMapping("/traditional")public List < Product > getAllProducts() {?System.out.println("Traditional way started");?List < Product > products = prodService.getProducts("traditional");?System.out.println("Traditional way completed");?return products;} |
在響應方法中,程序執行將繼續,而不用等待服務執行的完成。在下面的代碼中,在第一個 print 語句之后,第二個 print 語句將以非阻塞的方式執行,而無需等待服務執行的完成。Flux stream 將隨著產品數據的可用性而被填充。
?| 1234567 | @GetMapping(value = "/reactive", .TEXT_EVENT_STREAM_VALUE)public Flux < Product > getAll() {?System.out.println("Reactive way using Flux started");?Flux < Product > fluxProducts = prodService.getProductsStream("Flux");?System.out.println("Reactive way using Flux completed");?return fluxProducts;} |
Reactive Web Client
除了現有的 RestTemplate 之外,Spring 5 還引入了 Reactive WebClient。
ClientHttpRequest 和 ClientHttpResponse 抽象將請求和響應主體使用 Flux <DataBuffer> 公開,并在讀和寫端提供完全背壓支持。
來自 Spring Core 的編碼器和解碼器抽象也用在客戶端,用于將字節序的 Flus 序列化或發序列化成類型對象。
下面是一個 Reactive WebClient 的示例,它調用終端并接收及處理 Reactive Stream Flux 對象。
?| 12345 | @GetMapping("/accounts/{id}/alerts")public Flux < Alert > getAccountAlerts(@PathVariable Long id) {?WebClient webClient = new WebClient(new ReactorClientHttpConnector());?return this.repository.getAccount(id).flatMap(account -> webClient.perform(get("/alerts/{key}", account.getKey())).extract(bodyStream(Alert.class)));} |
Spring 5 的局限
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:
- Spring工廠方法創建(實例化)bean實例代碼
- Intellij IDEA 2017新特性之Spring Boot相關特征介紹
- jQuery+SpringMVC中的復選框選擇與傳值實例
- 淺談SpringMVC中post checkbox 多選框value的值(隱藏域方式)
- 淺談SpringBoot之開啟數據庫遷移的FlyWay使用
- 從SpringMVC遷移到Springboot的方法步驟
- Spring循環依賴正確性及Bean注入的順序關系詳解
- Spring的實例工廠方法和靜態工廠方法實例代碼
原文鏈接:https://www.oschina.net/translate/reactive-programming-with-spring-5
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的浅谈Spring5 响应式编程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java的HTTP服务端响应式编程
- 下一篇: 关于LR的自问自答