SpringBoot 2.0 響應式編程

SpringBoot 2.0 已經發布多時,一直不知道它有什麼用,只是知道它有個webflux。今天就來學習一下,看一下是否有必要升級到新版本?

1 2.0與1.0版本的區別?

官網圖

  • 咱們能夠看出來,增長了些新的特性,主要是對響應式編程的支持,底層多了Netty,這樣就能夠進行非阻塞io的編程,這也是響應式編程的基礎。
  • 還有就是2.0對應的java版本必須最低java8,支持java9.若是大家公司使用的仍是1.6,1.7那就不適合升級版本,可能會帶來一堆麻煩。
  • 使用webflux並不會提升應用的響應速度,官網也明確指出了。因此不要跟風去使用2.0的版本。
  • 使用webflux能夠在有限的資源下提升系統的吞吐量和伸縮性。

2 搭建簡單的webflux項目

若是你是使用得STS來建立項目的話將會很簡單,直接選擇web flux模塊就好。SpringBoot選擇最新穩定的2.1.4.RELEASE。前端

完整pom文件:java

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.mike</groupId>
    <artifactId>flux</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mike-flux</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</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>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

建立啓動類:(使用STS會自動建立)react

package com.mike;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MikeFluxApplication {

    public static void main(String[] args) {
        SpringApplication.run(MikeFluxApplication.class, args);
    }

}

3 編寫路由和處理類

有過前端工做經驗的小夥伴,對路由確定不陌生,Vue react中都有統一的路有管理。如今SpringBoot也能夠這樣來寫了。後端的小夥伴能夠把它理解爲你以前寫的controller。
先定義一個處理類:web

package com.mike.handler;

import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;

import reactor.core.publisher.Mono;

/**
 * The class HelloHandler
 * 
 */
@Component
public class HelloHandler {
    
    public Mono<ServerResponse> sayHello(ServerRequest req) {
        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON_UTF8)
                .body(BodyInserters.fromObject(req.queryParam("name").get()));
    }
}

Mono定義返回單個結果,定義了響應數據類型以及數據。我是從請求參數中取得name參數進行返回。spring

有了處理類,咱們就須要定義什麼樣的路由交給它來處理,要將路有何處理程序進行mapping:apache

package com.mike.router;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;

import com.mike.handler.HelloHandler;

/**
 * The class HelloRouter
 * 
 */
@Configuration
public class HelloRouter {
    
    @Bean
    public RouterFunction<ServerResponse> hello(HelloHandler handle){
        return RouterFunctions.route(RequestPredicates.GET("/hello")
                .and(RequestPredicates.accept(MediaType.APPLICATION_JSON_UTF8))
                ,handle::sayHello);
    }
}

咱們定義了/hello的請求交給咱們的處理類去處理,這樣一次完整的請求就搞定了。啓動程序,訪問http://localhost:8080/hello?name=mike 就能夠看到頁面上的結果了。編程

4 總結

  • 和1.0的版本相比,咱們編寫的程序返回結果將由MonoFlux來包裹。
  • 你能夠選擇使用路由的方式來編寫代碼,而不用寫controller
  • 異步響應,有時會帶來想不到的麻煩,斷點調試再也不有用。
  • 使用webflux 須要根據你本身的項目實際狀況來抉擇。若是你的項目中沒有調用別人的api,就不必使用webflux,用處不大,就像我上面搭建的項目。 若是須要請求別人的api,引入webflux,將會對超時,容錯,失敗重試有很好的改進,使得你的項目更完善,用戶體驗更好。

關於webflux若是你有更深的理解,但願能夠回覆一塊兒交流。後端

若是想要學習更多知識,能夠關注下個人公衆號:
mike啥都想搞api

相關文章
相關標籤/搜索