https://docs.spring.io/spring/docs/5.0.0.RELEASE/spring-framework-reference/web-reactive.html#webflux-introduction
Spring框架中所包含的最原始的web框架Spring Web MVC,是专门为Servlet API和Servlet容器构建的。而The reactive stack, web framework, Spring WebFlux是在后来Spring5.0版本中添加的,它是完全非阻塞的,支持Reactive Stream及背压,可以运行于Netty、Undertow等服务器,及Servlet 3.1+容器。
Spring WebFlux是一套全新的Reactive Web技术栈,实现完全非阻塞,支持Reactive Streams背压等特性,并且运行环境不限于Servlet容器(Tomcat、Jetty、Undertow),如Netty等。
https://docs.spring.io/spring/docs/5.0.0.RELEASE/spring-framework-reference/web-reactive.html#webflux-introduction
这两个Web框架都反映了它们的源模块spring-webmvc和spring-webflux的名称,并在Spring Framework中并存。
Spring WebFlux与Spring MVC可以共存,在SpringBoot中,Spring MVC优先级更高。
动机
https://docs.spring.io/spring/docs/5.0.0.RELEASE/spring-framework-reference/web-reactive.html#webflux-new-framework
部分原因是需要一种非阻塞式的Web技术栈,以少量线程处理并发,并使用更少的硬件资源进行伸缩。Servlet 3.1确实提供了用于非阻塞I/O的API。但是,仍然有部分Severlet API存在同步(如Filter,Servlet)或者阻塞(getParameter,getPart)的情况。这是促使新的通用API成为所有非阻塞运行时的基础的动机。而Netty之类的服务器已经以异步,非阻塞的方式很好的运行。(这部分观点不太严谨,tomcat及servlet3.0已支持非阻塞方式)
另一部分原因是函数式编程。就像在Java 5中新增的注释功能为开发提供了更多的可能性,而现在带注释的REST控制器或单元测试,以及在Java 8中增加的lambda表达式则为Java中的函数式api创造了基础。
这对于非阻塞应用程序,和由CompletableFuture和ReactiveX推广的api来说是一个福音,可以以声明的方式构成异步逻辑。在编程模型级别上,Java8支持Spring WebFlux提供functional web ednpoints以及带注解的控制器。(这部分观点依然不太严谨,vert.x早就实现了reactive编程,函数式编程)
实际动机
从Spring MVC注解驱动的时代开始,Spring官方有意识的去Servlet化,不过在Spring MVC的时代,Spring扔摆脱不了Servlet容器的依赖,然而Spring借助Reactive Programming的势头,WebFlux将Serverlet容器从必须项变为可选项,并且默认采用Netty Web Server作为基础,从而逐渐的形成Spring全新的技术体系,包括数据存储等技术栈。
编程模型 注解驱动(Annotated Controllers)
https://docs.spring.io/spring/docs/5.2.8.RELEASE/spring-framework-reference/web-reactive.html#webflux-controller
与spring mvc相同
Spring WebFlux提供了一个基于注解的编程模型,@Controller和@RestController组件使用注解来表示请求映射、请求输入、处理异常等等。
带注释的控制器具有灵活的方法签名,无需扩展基类或实现特定的接口。
定义
特性
Spring Web MVC
SpringWebFlux
应用控制器注解声明
@Controller
相同
应用REST控制器注解声明
@RestController
相同
映射
特性Spring Web MVC
SpringWebFlux
请求映射注解声明
@RequestMapping
相同
GET方法映射
@GetMapping
相同
POST方法映射
@PostMapping
相同
PUT方法映射
@PutMapping
相同
DELETE方法映射
@DeleteMapping
相同
PATCH方法映射@PatchMapping
相同
请求
特性Spring Web MVCSpringWebFlux获取请求参数
@RequestParam
相同获取请求头
@RequestHeader
相同获取Cookie值
@CookieValue
相同获取完整请求主体内容
@RequestBody
相同获取请求路径变量
@PathVariable
相同获取请求内容(包括请求主体和请求头)
RequestEntity
相同响应
特性Spring Web MVCSpringWebFlux
响应主体注解声明
@ResponseBody
相同响应内容(包括响应主体和响应头)
ResponseEntity
相同
响应Cookie内容
ResponseCookie
相同
拦截
特性Spring Web MVCSpringWebFlux@Controller注解切面通知
@ControllerAdvice
相同
@ResetController注解切面通知
@RestControlerAdvice
相同
跨域
特性
Spring Web MVCSpringWebFlux资源跨域声明注解
@CrossOrigin
相同
资源跨域拦截器
CorsFilter
CorsWebFilter
注册资源跨域信息
WebMvcConfigurer#addCorsMappings
WebFluxConfigurer#addCorsMappings
函数式端点(Functional Endpoints)
映射路由接口 - RouterFunction
函数映射
RouterFunction<ServerResponse> route = route() .GET("/person/{id}", accept(APPLICATION_JSON), handler::getPerson) .GET("/person", accept(APPLICATION_JSON), handler::listPeople) .POST("/person", handler::createPerson) .build();函数处理接口
public class PersonHandler { // ... public Mono<ServerResponse> listPeople(ServerRequest request) { // ... } public Mono<ServerResponse> createPerson(ServerRequest request) { // ... } public Mono<ServerResponse> getPerson(ServerRequest request) { // ... }}示例
@SpringBootApplicationpublic class WebFluxApplication { public static void main(String[] args) { SpringApplication.run(WebFluxApplication.class, args); } @Bean public RouterFunction<ServerResponse> routerFunction() { // mode 1 return route() .GET("/hello-world", accept(MediaType.APPLICATION_JSON) , request -> ServerResponse.status(HttpStatus.OK).body(Mono.just("Hello world"), String.class)) .build(); // mode 2 return route(request -> { URI uri = request.uri(); return "/hello-world".equals(uri.getPath()); }, request -> ServerResponse.status(HttpStatus.OK).body(Mono.just("Hello,World."), String.class)); }}并发模型
核心组件 HttpHandler API
HttpHandler是一种带有处理HTTP请求和响应方法的简单契约。
接口定义:
public interface HttpHandler { /** * Handle the given request and write to the response. * @param request current request * @param response current response * @return indicates completion of request handling */ Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response);}WebHandler API Bean nameBean typeCountDescription
<any>
WebExceptionHandler
0..N
Provide handling for exceptions from the chain of WebFilter instances and the target WebHandler. For more details, see Exceptions.
<any>
WebFilter
0..N
Apply interception style logic to before and after the rest of the filter chain and the target WebHandler. For more details, see Filters.
webHandler
WebHandler
1
The handler for the request.
webSessionManager
WebSessionManager
0..1
The manager for WebSession instances exposed through a method on ServerWebExchange. DefaultWebSessionManager by default.
serverCodecConfigurer
ServerCodecConfigurer
0..1
For access to HttpMessageReader instances for parsing form data and multipart data that is then exposed through methods on ServerWebExchange. ServerCodecConfigurer.create() by default.
localeContextResolver
LocaleContextResolver
0..1
The resolver for LocaleContext exposed through a method on ServerWebExchange. AcceptHeaderLocaleContextResolver by default.
forwardedHeaderTransformer
ForwardedHeaderTransformer
0..1
For processing forwarded type headers, either by extracting and removing them or by removing them only. Not used by default.
Web MVC vs WebFlux执行流程
注解驱动(Annotated Controllers)组件请求处理流程