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>
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
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);
}
}
随后启动我们的服务,再通过浏览器访问我们的接口就可以了。
上面三个接口的访问结果如下
hello
user-get
user-list
可以看到我们在浏览器可以正常获取到数据,上面的代码跟我们平时写 SpringMVC
的代码很相似,不太一样的地方是有两个类 Mono
和 FLux
。
关于 Mono 和 Flux 是反应式编程的概念,Mono 是返回 0 或 1 个元素,Flux 是返回 0 - N 个元素,更详细的内容大家可以通过官方文档 https://projectreactor.io/docs/core/release/api/ 来查看
总结
虽然从上面的写法来看,Spring WebFlux
的写法与 SpringMVC
的写法没有很大的区别,但是两者的底层机制是完全不一样的,而且技术栈也不完全相同,所以大家在日常技术选型的时候需要根据实际情况去选择。
阿粉这里给出的建议就是,如果当下的项目就是 SpringMVC
的,那么不要想着换成 Spring WebFlux
架构,因为没必要,如果说要新开发一个项目,需要高吞吐量而且底层也不依赖事务性数
据库的话,那么可以尝试使用一下 Spring WebFlux
。
来源: Java极客技术
作者:鸭血粉丝Tang