實戰SpringCloud:使用Spring WebFlux構建響應式RESTful服務

實戰SpringCloud:使用Spring WebFlux構建響應式RESTful服務

WebFlux名稱中的Flux來自Reactor框架中的Flux組件。該框架中包含了對響應式HTTP、服務器推送事件以及Websocket的客戶端和服務端的支持。

在構架響應式服務上,WebFlux支持兩種不同的編程模型:

  • 第一種是與SpringMvc中同樣使用的基於java註解的方式;
  • 第二種是基於java8中提供的lambda表達式的函數式編程模型。

1.1使用 Spring Initializer初始化響應式web應用

創建WebFlux應用最簡單的方式便是使用Spring boot提供的Spring Initializer初始化模板。

直接訪問Spring Initializer網站(http://start.spring.io),選擇創建一個maven或者Gradle項目並制定相應的Group和Artifact,然後在添加依賴中選擇maven進行代碼依賴管理。

實戰SpringCloud:使用Spring WebFlux構建響應式RESTful服務

打開所下載項目中的pom文件,會找到如下依賴。

  • 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>

<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>

<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的關係可以自行百度瞭解,這裡不做過多介紹。

1.2使用註解編程模型創建響應式RESTful服務

基於註解編程模型來創建響應式RESTful服務與使用傳統SpringMvc非常類似。通過掌握響應式編程的基本概念和技巧,在webflux中使用這種編程模型幾乎沒有任何學習成本。

構建第一個響應式RESTful服務

第一個響應式RESTful服務來自於對之前HelloController示例進行改造,改造之後的代碼如下:

@RestController
public class Helloontroller{
@GetMapping("/")
public Mono<string> index(){
return Mono.just("Hello Spring Boot");
}
}
/<string>

以上代碼只有一個地方值得注意,即index()方法的返回值類型是Mono<string>類型,其中包含的字符串"Hello Spring Boot"或作為HTTP的響應內容。/<string>

在瀏覽器中訪問會得到如下結果:

實戰SpringCloud:使用Spring WebFlux構建響應式RESTful服務

從以上代碼可以看到使用Spring WebFlux和使用 Spring Mvc的不同在於,WebFlux所使用的類型是與響應式編程相對應的Flux和Mono對象,而不是簡單的POJO,對於簡單的Hello Word實力來說,這兩個之間並沒有什麼太大的差別。

但是對於複雜的應用來說,響應式編程的背壓機制就會體現出來,可以帶來整體性能的提升。在後續講解中會有完整示例代碼。

1.3使用函數式模型創建響應式RESTful服務

這部分內容與傳統的SpringMvc構建RESTful服務有較大的差別。

(1)函數式編程模型

在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消息的友好訪問。/<serverresponse>

具體代碼示例如下:

public class HelloWordHandlerFunction impllements HandlerFunction<serverresponse>{
@Override
public Mono<serverresponse> handle(ServerRequest request){
return ServerResponse.ok().body(BodyInserters.fromObject("Hello Word"))
}
}
/<serverresponse>/<serverresponse>

關於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)
}
}
/<serverresponse>

(2)RouterFunction

上面我們已經通過HandlerFunction創建了請求的邏輯處理,接下來需要把具體的邏輯關聯起來,RouterFunction可以幫助我們實現這一個目標。RouterFunction將傳入的請求路由傳入到具體的函數,它接收ServerRequest 並返回一個Mono<serverresponse>。/<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)
}
}
/<serverresponse>

最後,小編這裡針對以上問題整理更多spring的學習資料,更有阿里大牛的spring源碼剖析視頻 可以分享給大家。

轉發關注後,後臺私信我【資料】即可獲得資料免費領取方式!

實戰SpringCloud:使用Spring WebFlux構建響應式RESTful服務

實戰SpringCloud:使用Spring WebFlux構建響應式RESTful服務


分享到:


相關文章: