Spring Webflux是Spring 5.0之后新加入的响应式web框架,它支持Reactive-stream背压策略,并且是完全非阻塞的,运行在Netty ,Undertown等servlet 3.1+容器中。
作为开发者,可以选择SpringMVC或者WebFlux,也可以同时使用两种框架。
Spring Webflux框架创建的背景?
- 互联网快速发展,需要一种非阻塞的并发方式在扩容的时候使用少量的线程和系统资源,虽然Servlet3.1已经引入了非阻塞的API操作,但是其还有一些操作是阻塞的。想要创建一种完全非阻塞的方式
- 另一个原因是Java函数式编程的特性,在JDK1.8之后引入的函数式编程特性使得webflux采用函数式编程入口成为可能。
关于响应式,有几个特性:异步,事件驱动,扩展观察者模式,扩容时消耗资源少,关注数据与数据的变化。
官方宣言:https://www.reactivemanifesto.org/
响应式API
前段时间,探讨过RxJava的一些特性与操作符,目前市场上的响应式框架都实现了Reactive Streams 的接口,大家用起来都大同小异,都有几个基本组成:
- 被观察者,观察者,背压,操作符,线程切换
Spring Webflux依赖的Reactor Core也是如此, 被观察者有两个关键类
- Mono 0..1的数据序列
- Flux 1..N的数据序列
其余对比RxJava。
编程模型
Spring Webflux支持两种编程模型:
- 注解方式:与Spring MVC保持一致,@RequestMapping,@Controller之类的,与Spring MVC完全兼容,如下
// 经常使用的方式
@RestController
@RequestMapping("/")
public class IndexController {
@GetMapping
public String index(){
return "index";
}
}
- 函数式入口: 采用Lambda表达式,集中声明一些应用的入口与处理方式。
// 函数式入口编程
@Bean
public RouterFunction routerFunction() {
return RouterFunctions.route()
.GET("/", req -> ServerResponse.ok().body(Mono.just("index"), String.class))
.build()
;
}
MVC & WebFlux对比
关于要采用WebFlux还是MVC上,在使用前做一番探索是否真的需要Webflux。
WebFlux关键组件
- HttpHandler:低级别的Http请求处理,
- WebHandler: 看做是比较HttpHandler高一级的接口,更加通用
WebExceptionHandler,WebFilter,WebSessionManager,ServerCodecConfigurer,LocaleContextResolver,ForwardedHeaderTransformer
代码
MVC和WebFlux用起来实在是非常的相似,重点要关注两者之间到底有什么区别,还是演示一下代码。
1 引入maven依赖。记得引入web-starter
依赖,mvc与webflux都是基于web框架的。
<?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.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>me.aihe</groupId>
<artifactId>webflux-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
</dependencies>
</project>
2 写一个函数式入口。
@SpringBootApplication
public class WebFluxApplication {
public static void main(String[] args) {
SpringApplication.run(WebFluxApplication.class, args);
}
@Bean
public RouterFunction routerFunction() {
return RouterFunctions.route()
.GET("/", req -> {
System.out.println("当前线程:"+ Thread.currentThread().getName());
return ServerResponse.ok().body(Mono.just("index"), String.class);
})
.build()
;
}
}
3 运行一下,用户无法感受到用的是mvc还是webflux。
最后
关于WebFlux,重点还是要关注其与MVC的区别,后续继续完善。
参考: