您的位置:

详解Spring WebFlux

一、异步和非阻塞

Spring WebFlux是Spring框架的一部分,是基于异步和非阻塞的Web框架。传统的Web服务器中,每个请求都会开启一个线程,大量的并发请求会导致线程池资源耗尽。而Spring WebFlux则采用了事件驱动、响应式编程的方式,通过少量的线程来处理大量的请求。

与传统的Servlet容器相比,Spring WebFlux 提供了两种不同的前端编程模型,分别是基于Servlet和基于Reactive。其中基于Servlet的WebFlux风格类似于Spring MVC的编程模型,基于Reactive的WebFlux则使用更加高级的技术。它具有异步和流异步的能力,可以支持更高的并发性和更好的响应时间。

在代码实现上,我们可以使用Java 8的新特性reactive-streams或者是Reactor来实现。

二、响应式编程

Spring WebFlux基于响应式编程,其核心概念是流的概念。通过流的形式,我们可以将数据按照一定的模式进行传输,这样就可以非阻塞地获取数据。

在响应式编程中,数据流是不可变的,每个数据流的结果都可以是一个值、空值或错误。数据流中的每个值都可以进行转换和处理,从而生成新的数据流,这样就可以构建复杂的数据处理管道。

Spring WebFlux通过实现 reactive-streams 标准,来保证对响应式编程风格的支持。你可以将streaming 结合到你在控制器中的方法中,也可以使用Flux或Mono从数据存储、或者某个service中读取数据,并且实现异步的HTTP响应.

三、Router 和 Handler

Spring WebFlux没有类似于Spring MVC的@Controller,而是通过HandlerFunction接口和RouterFunction接口来实现请求的处理。HandlerFunction是一个处理一个HTTP请求的函数,它是Spring WebFlux中的最基本的处理单元。而RouterFunction则是一个创建处理器Pipeline的函数。

当请求到达Spring WebFlux的Servlet容器时,Servlet容器会将请求传递给一个HandlerAdapter,该Adapter会获取路由信息,并调用路由的方法取出对应的HandlerFunction 来处理请求。HandlerFunction就是一个处理由RouterFunction映射的请求路由的函数。

我们通过RouterFunction来实现URL映射,定义HTTP请求的路由,而HandlerFunction是用来处理请求和响应的。这样,我们就可以实现更好的解耦——路由负责将请求路由到正确的地方,而处理程序则负责处理页面或逻辑。

@RestController
public class GreetingController {
 
    @GetMapping("/hello/{name}")
    public Mono<String> hello(@PathVariable String name) {
        return Mono.just("Hello " + name + "!");
    }
 
    @GetMapping("/greetings")
    public Flux<String> greetings() {
        return Flux.just("Hello Reactive World!", "Bonjour le monde Reactive !", "Hallo Reactive Welt!");
    }
}

四、服务器推送(Server Sent Events)

Server Sent Event是HTML 5规范中的API之一,经过浏览器原生支持。它允许服务器端将数据推送到客户端,而无需客户端先请求。

在Spring WebFlux中,我们可以通过MediaType.TEXT_EVENT_STREAM_VALUE指定媒体类型来实现服务端推送。代码实现时,在处理器函数中我们可以发出一个无限流包含任意对象。一个无限流可以通过Flux.generate()方法创建。

@GetMapping(value = "/sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<ServerSentEvent<Greeting>> sse() {
    return Flux.interval(Duration.ofSeconds(1))
            .map(sequence -> ServerSentEvent.builder(new Greeting("Hello, SSE!")).build());
}

五、WebClient

WebClient是Spring WebFlux提供的一个非阻塞和响应式的HTTP客户端,用于调用其他的HTTP服务。我们可以在不同的WebFlux应用程序之间建立连接。我们甚至可以将非WebFlux应用程序集成到我们的WebFlux应用程序中。

WebClient webClient = WebClient.create("https://api.github.com");
 
Mono<User> userMono = webClient.get()
        .uri("/users/{username}", "lovelyorg")
        .retrieve()
        .bodyToMono(User.class);
 
userMono.subscribe(user -> System.out.println("user = " + user));

六、结论

Spring WebFlux是Spring框架的一个强有力的补充,它提供异步和响应式的Web编程模型,为我们的应用程序带来了更高的并发能力和更好的响应时间。在实际的应用程序开发中,我们可以使用Spring WebFlux来构建高性能、高可用、高并发的Web应用程序。