Servlet web 我们天天使用很熟悉,那什么是 Reactive web 呢?两者的区别是啥?今天阿粉就给大家介绍一下。

Servlet 与 Reactive 技术栈

打开 Spring 的官方文档我们在 Reactive 一栏中可以看到下面的架构图,其中可以很明显的看到 Reactive 的技术栈跟 Servlet 技术栈是完全并行的。意思是说我们日常开发的 Servlet web 类型只是一半的内容,还有另外一半世界就是 Reactive,两者对应的依赖如下所示。




<!--Servlet web 依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--Reactive web 依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>

servletResponse header设置_java

servlet-reactive

通过架构图我们可以知道常用的 Servlet web 就是我们经常说的 Spring MVC,底层的技术栈支持 JDBC 等,而 Reactive web 就是 Spring WebFlux 底层的持久层支持 Mongo 等但是不支持 JDBC。

什么是 Spring WebFlux

由上图我们看到 Spring WebFlux 是一个异步非阻塞式的 Web 框架,它能够充分利用多核 CPU 的硬件资源去处理大量的并发请求。相对于 Spring MVC 来说的话,Spring MVC 构建于 Servlet API 之上,使用的是同步阻塞式 I/O 模型。

由于 Spring WebFlux 底层是使用响应式编程,基于事件的异步驱动,所以可以在很大程度上提升系统的吞吐量。但是要知道这并不会缩短请求的响应时间,只是提升吞吐量。

而且根据上面的架构图我们可以发现,Spring WebFlux 底层的持久层是不支持 JDBC 的,也就是说不支持 MySQL 等事务性数据库,

举个栗子

前面说了这么多那 Spring WebFlux 到底是怎么开发的呢?下来通过一个简单的 case 来给大家演示一下。在演示之前通过官方文档我们可以发现,Spring WebFlux 和 Spring MVC 是可以共用很多组件的,比如 @Controller,Tomcat 等,但是也会存在很多差异。

Spring 官方 Reactive 地址为:https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html

servletResponse header设置_spring_02


springmvc-springwebflux

基于我们之前的 demo-reactive 项目的代码,或者小伙伴也可以在 starter.spring.io 上面下载一个 SpringBoot 的项目代码,增加上 spring-boot-starter-webflux 依赖即可。

定义 DTO




package com.example.reactive.demoreactive.dto; public class User { private String name; private int age; //省略 getter setter }

定义 Controller




package com.example.reactive.demoreactive.controller; import com.example.reactive.demoreactive.dto.User; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import java.util.ArrayList; import java.util.List; @RestController public class UserController { @GetMapping("/hello") public String sayHello() { return "hello"; } @GetMapping("/user/get") public Mono<User> getUser() { User user = new User(); user.setName("Java极客技术"); user.setAge(18); return Mono.just(user); } @GetMapping("/user/list") public Flux<List<User>> getAllUser() { User user = new User(); user.setName("Java极客技术"); user.setAge(18); List<User> list = new ArrayList<>(); list.add(user); return Flux.just(list); } }

随后启动我们的服务,再通过浏览器访问我们的接口就可以了。

servletResponse header设置_servlet_03


上面三个接口的访问结果如下

servletResponse header设置_java_04


hello

servletResponse header设置_MVC_05


user-get

servletResponse header设置_java_06


user-list

可以看到我们在浏览器可以正常获取到数据,上面的代码跟我们平时写 SpringMVC 的代码很相似,不太一样的地方是有两个类 Mono 和 FLux。


总结

虽然从上面的写法来看,Spring WebFlux 的写法与 SpringMVC 的写法没有很大的区别,但是两者的底层机制是完全不一样的,而且技术栈也不完全相同,所以大家在日常技术选型的时候需要根据实际情况去选择。

阿粉这里给出的建议就是,如果当下的项目就是 SpringMVC 的,那么不要想着换成 Spring WebFlux 架构,因为没必要,如果说要新开发一个项目,需要高吞吐量而且底层也不依赖事务性数据库的话,那么可以尝试使用一下 Spring WebFlux。