本文爲實戰SpringCloud響應式微服務系列教程第九章,講解使用Spring WebFlux構建響應式RESTful服務。建議沒有以前基礎的童鞋,先看以前的章節,章節目錄放在文末。html
從本節開始咱們將正式進入構建響應式服務的世界。在Spring boot的基礎上,咱們將引入全新的Spring WebFlux框架。java
WebFlux名稱中的Flux來源於上章節介紹的來自Reactor框架中的Flux組件。該框架中包含了對響應式HTTP、服務器推送事件以及Websocket的客戶端和服務端的支持。react
在構架響應式服務上,WebFlux支持兩種不一樣的編程模型:web
建立WebFlux應用最簡單的方式即是使用Spring boot提供的Spring Initializer初始化模板。redis
直接訪問Spring Initializer網站(http://start.spring.io),選擇建立一個maven或者Gradle項目並制定相應的Group和Artifact,而後在添加依賴中選擇maven進行代碼依賴管理。spring
打開所下載項目中的pom文件,會找到以下依賴。mongodb
- spring-boot-starter-webflux構成響應式web程序開發的基礎;
- spring-boot-starter-test是包含JUnit、Spring boot Test、Mockito、AssertJ、JSONAssert以及Hamcerst等工具在內的測試組件庫;
- reactor-test則是用來測試Reactor框架的測試組件;
- spring-boot-starter-data-mongodb-reactive和spring-boot-starter-data-redis-reactive則是響應式數據訪問組件。
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <!--Lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> <version>1.16.22</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId> </dependency> <!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis-reactive</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-test</artifactId> <scope>test</scope> </dependency> </dependencies>
至此,使用Spring WebFlux構架響應式服務的基礎環境已經準備完畢。編程
關於Spring WebFlux和傳統的SpringMvc的關係能夠自行百度瞭解,這裏不作過多介紹。瀏覽器
基於註解編程模型來建立響應式RESTful服務與使用傳統SpringMvc很是相似。經過掌握響應式編程的基本概念和技巧,在webflux中使用這種編程模型幾乎沒有任何學習成本。服務器
第一個響應式RESTful服務來自於對以前HelloController示例進行改造,改造以後的代碼以下:
@RestController public class Helloontroller{ @GetMapping("/") public Mono<String> index(){ return Mono.just("Hello Spring Boot"); } }
以上代碼只有一個地方值得注意,即index()
方法的返回值類型是Mono<String>
類型,其中包含的字符串"Hello Spring Boot"或做爲HTTP的響應內容。
在瀏覽器中訪問會獲得以下結果:
從以上代碼能夠看到使用Spring WebFlux和使用 Spring Mvc的不一樣在於,WebFlux所使用的類型是與響應式編程相對應的Flux和Mono對象,而不是簡單的POJO,對於簡單的Hello Word實力來講,這兩個之間並無什麼太大的差異。
可是對於複雜的應用來講,響應式編程的背壓機制就會體現出來,能夠帶來總體性能的提高。在後續講解中會有完整示例代碼。
這部份內容與傳統的SpringMvc構建RESTful服務有較大的差異。
在Spring WebFlux中,函數式編程模型的核心概念是Router Functions,對標@Controller
、@RequestMapping
等標準的Spring Mvc註解。
Router Functions提供一套函數式的API,用於建立Router和Handler對象。其中咱們能夠簡單的把Handler對應爲Controller,把Router對應爲RequestMapping。
當咱們發起一個遠程調用時,傳入的HTTP請求由HandlerFunction處理,HandlerFunction本質上是一個接收ServerRequest並返回一個Mono<ServerResponse>
的函數。ServerRequest和ServerResponse是一個不可變的接口,用來提供對底層HTTTP消息的友好訪問。
具體代碼示例以下:
public class HelloWordHandlerFunction impllements HandlerFunction<ServerResponse>{ @Override public Mono<ServerResponse> handle(ServerRequest request){ return ServerResponse.ok().body(BodyInserters.fromObject("Hello Word")) } }
關於ServerRequest和ServerResponse咱們在這裏不作過多介紹,詳細瞭解可查閱相關資料。
以上代碼將ServerRequest和ServerResponse組合到一塊兒建立了HandlerFunction。HandlerFunction是一個接口,能夠經過實現該接口中的handl()
方法來建立定製化的請求響應處理機制。
一般咱們會針對某個領域實體對象編寫多個處理函數,因此推薦將多個處理函數分組到一個專門的Handler類中。例如咱們編寫一個PersonHandler專門實現各類針對Person領域對象的處理函數。
代碼以下:
public class PersonHandler{ @Autowired private PersonService personService; public Mono<ServerResponse> getPersons(ServerRequest request){ return ServerResponse.ok().body(this.personService.getPersons(),Person.class) } }
上面咱們已經經過HandlerFunction建立了請求的邏輯處理,接下來須要把具體的邏輯關聯起來,RouterFunction能夠幫助咱們實現這一個目標。RouterFunction將傳入的請求路由傳入到具體的函數,它接收ServerRequest 並返回一個Mono<ServerResponse>
。
若是請求與特定路由匹配則返回處理函數的結果,不然返回一個空的Mono對象。RouterFunction與@ReuestMapping相似。代碼以下:
public class personRouter{ @Bean public RouterFunction<ServerResponse> routerPerson(PersonHandler personHandler){ return RouterFunctions.route(RequestPredicates.GET("/person") .add(RequestPredicates.accept(MediaType.APPLICATION_JSON)), personHandler::getPersons) } }
本章節完
原文出處:https://www.cnblogs.com/javazhiyin/p/11790688.html