使用Spring WebFlux構建響應式API

使用Spring WebFlux構建響應式API

在Spring 5中,提供了一個新的組件:Spring WebFlux。

Spring WebFlux是在響應式編程的浪潮下誕生的。它基於Reactor網絡框架,提供了異步I/O,使應用的性能更好。我們原先都是使用Spring MVC構建REST API,同樣,Spring WebFlux出了幾個概念不同,其他的思想還是和以前相似的。

開始使用響應式編程和Spring WebFlux

首先我們來創建一個基於Spring WebFlux的項目。

Spring為我們提供了非常強大的構建工具:Spring Initializr(https://start.spring.io),通過這個工具,我們可以快速的構建一個基於Spring框架的項目。

在Idea開發工具中,集成了Spring Initializr。

在Eclipse開發工具中,Spring提供了STS工具。

使用Spring WebFlux構建響應式API

配置如下:

項目: Maven項目

語言:Java

Spring Boot版本:2.1.5

項目元數據:

Group: com.example

Artifact: demo

項目依賴:

DevTools

Reactive Web

Reactive MongoDB

Lombok

然後執行生成項目,會自動下載zip包,我們解壓文件,可以看到如下的項目格式:

使用Spring WebFlux構建響應式API

pom.xml是Maven的構建文件,非常簡單。

我們首先升級單元測試工具JUnit,將JUnit升級到 JUnit 5,它是一個更現代的測試框架,在Spring 5得到了很好的支持。

將以下依賴項添加到新應用程序的構建文件pom.xml中:org.junit.jupiter:junit-jupiter-engine並對其進行測試。 然後,從spring-boot-starter-test依賴項中排除junit:junit依賴項。 同時,我們還需要添加對嵌入式MongoDB的依賴,為我們的單元測試,提供MongoDB服務。

這是生成的pom.xml:

使用Spring WebFlux構建響應式API

這是一個標準的Spring Boot應用程序,帶有一個公共靜態void main(String [] args)入口點類DemoApplication.java:

使用Spring WebFlux構建響應式API

此類在 src/test/java/com/example/demo/DemoApplicationTests.java 中有一個測試,我們需要針對JUnit 5更新該測試。

使用Spring WebFlux構建響應式API

在項目中,我們還可以看到有一個空的配置文件: src/main/resources/application.properties.

我們的基本項目基本準備已完成,接下來,添加數據訪問相關的內容。

使用Spring數據添加響應性數據訪問

想要做基於數據庫的響應式編程,需要我們的數據庫驅動程序本身具有支持異步I/O等能力,否則我們將無法在不擴展線程的情況在進行響應式讀寫操作。

Spring Data是一個傘形數據訪問框架,它支持許多反應式數據訪問選項,包括響應式Cassandra,MongoDB,Couchbase和Redis。 在這裡我們選擇了MongoDB,因此請確保您在本地主機上的默認主機,端口上運行了一個MongoDB數據庫實例,並且可以使用默認的用戶名和密碼進行訪問。

在Win10下安裝MongoDB請參考:

接下來,在com.example.demo包中創建一個Profile實體類。 給它一個字段,電子郵件以及另一個將用作文檔ID的字段。 該實體將保留在MongoDB中。

使用Spring WebFlux構建響應式API

// 1 @Document 將實體標識為要在MongoDB中保留的文檔

// 2 @Data , @AllArgsConstructor 和 @NoArgsConstructor 均來lombok。 它們是編譯時註釋,告訴lombok生成 getter / setter ,構造函數, toString() 方法和equals方法。

// 3 @Id 是Spring Data註解,用於標識此文檔的文檔ID

為了持久保存Profile類型的文檔,我們以聲明的方式定義了一個存儲庫。 存儲庫是Eric Evans的經典著作《域驅動設計》中的一種設計模式,是一種封裝對象持久性的方法。

存儲庫負責持久化實體和值類型。 他們為客戶提供了一個簡單的模型,用於獲取持久性對象並管理其生命週期。 它們使應用程序和領域設計與持久性技術和策略選擇解耦。

創建一個Spring Data存儲庫, src/main/java/com/example/demo/ProfileRepository.java

使用Spring WebFlux構建響應式API

該存儲庫擴展了Spring Data提供的ReactiveMongoRepository接口,該接口又提供了許多支持讀取,寫入,刪除和搜索的數據訪問方法,幾乎所有方法都接受或返回 Publisher類型的方法簽名。

使用Spring WebFlux構建響應式API

Spring Data將創建一個實現所有這些方法的對象。 它將為我們提供一個對象,我們可以將其注入其他對象以處理持久性。

如果我們創建一個繼承ReactiveMongoRepository的空的存儲庫,我們就不需要額外為該存儲庫創建測試用例,因為它一定會“正常工作”。

Spring Data存儲庫還支持自定義查詢。 例如,我們可以在ProfileRepository中定義Flux <profile> findByEmail(String email)形式的自定義查找方法。 這將導致定義一個方法,該方法在MongoDB中查找所有謂詞,該謂詞將文檔中的email屬性與方法名稱中的參數email匹配。 如果您定義自定義查詢,那麼這可能是一個合適的測試對象。/<profile>

Spring數據倉庫也支持自定義查詢。例如,我們可以在我們的配置文件數據庫中定義一個自定義的查找方法,形式為Flux<profile>查找方式郵件(字符串電子郵件)。這將導致定義一個方法,該方法使用謂詞在MongoDB中查找所有文檔,該謂詞將文檔中的電子郵件屬性與方法名稱中的參數email相匹配。如果您定義了自定義查詢,那麼這可能是一個合適的測試。/<profile>

當然,這是一個示例應用程序,因此我們需要一些示例數據來使用。 當應用程序啟動時,讓我們運行一些初始化邏輯。 當應用程序啟動時,我們可以定義類型為ApplicationListener <applicationreadyevent>的bean。 一旦應用程序啟動,這對我們來說是一個令人羨慕的機會,可以將一些示例數據寫入數據庫。/<applicationreadyevent>

創建SampleDataInitializer.java類以在啟動時初始化數據庫數據。

使用Spring WebFlux構建響應式API

響應式service

我們將使用存儲庫來實現一項服務,該服務將包含所有過程細化的業務邏輯。 在開始時,許多業務邏輯將通過委派給存儲庫的邏輯傳遞,但是我們可以在此層添加諸如驗證和與其他系統集成的功能。 創建一個ProfileService.java類。

使用Spring WebFlux構建響應式API

ProfileCreatedEvent與其他任何Spring ApplicationEvent一樣。

使用Spring WebFlux構建響應式API

還不錯吧? 我們的服務非常簡單。 唯一的新穎之處是事件的發佈。 現在一切都應該正常工作。 但是,當然,除非進行測試,否則我們不可能知道。

為響應式服務添加測試

創建 ProfileServiceTest 來測試我們寫的服務 ProfileService 。

使用Spring WebFlux構建響應式API

我們僅完成了一項測試,因為其餘測試沒有什麼變化且相似。 您可以運行mvn test來確認測試能夠按預期進行。

StepVerifier對測試所有反應性至關重要。 它為我們提供了一種斷言,認為我們認為發佈者中接下來將要發生的事情實際上是發佈者中接下來將要發生的事情。 StepVerifier在Expect *主題上提供了幾種變體。 將此視為與Assert *的等效。

JUnit 5支持與JUnit 4相同的生命週期方法和註釋(例如@Before)。這很棒,因為它為您提供了一個位置來設置類中的所有測試,或拆除測試之間的機制。 也就是說,我不會在setUp方法中訂閱任何反應式初始化管道。 相反,您可以在設置中定義Flux ,然後在測試方法的主體中進行組合。 這樣,您不必懷疑設置是否在測試本身執行之前就已經完成。


分享到:


相關文章: