快速使用WebFlux
前一篇咱快速的了解了响应式编程,以及 Reactor 框架的基本使用,接下来咱要开始正式接触 WebFlux 了。
咱都知道,自打 SpringFramework5 发行后,之前的 SpringMVC 被改名为 SpringWebMvc,因为它多了一个兄弟叫 SpringWebFlux 。而且 Spring 的开发者们为了避免咱们这些使用者因为新技术的门槛过高而吓跑,WebFlux 可以完美使用 WebMvc 的开发风格。下面咱先实战使用 WebFlux 框架,但还是用 WebMvc 的开发风格。
1. WebFlux环境下用WebMvc风格
导入的依赖还是咱上一篇提到的 spring-boot-starter-webflux
,没有引入 WebMvc 模块,直接运行主启动类,观察控制台的输出:
注意看应用启动在 Netty 上而不是 Tomcat 了!因为 Netty 更适合做响应式编程的应用服务器。
接下来,跟之前开发 WebMvc 应用一样,咱编写一个 DemoController
:
之后用浏览器或者 postman 发送请求:http://localhost:8080/test ,能正常响应 "test"
字符串,证明 WebFlux 可以完美兼容 WebMvc 的开发风格。
2. 逐步过渡到WebFlux
在上一篇咱看到了,Reactor 中的核心数据的封装是 Flux
和 Mono
,那下面咱来改造上面的 DemoController
,用上这两个组件:
如果只返回一个对象,则使用 Mono
替换,返回列表则使用 Flux
替换。
但这样写的话,只是替换了返回值类型,注解还是原来 WebMvc 中的,SpringWebFlux 有自己的专门一套开发 Controller
层的API,那就是函数式开发。
3. WebFlux的函数式开发
在切换完全不同的开发风格之前,先大概想一下之前的 WebMvc 部分,关键点都有哪些:
Controller 类上要打
@Controller
或者@RestController
注解url映射的方法要在方法上打
@RequestMapping
注解或者它的扩展注解
咱之前分析 WebMvc 的原理时也知道,这些 Controller
中的方法,最终都会封装为一个一个的 **Handler**
,每个 Handler
都有自己匹配的 url。
由此,WebFlux 的函数式开发的核心点就转换为两种关键组件:**HandlerFunction**
和 **RouterFunction**
。
3.1 DemoController转换为DemoHandler
先将 WebMvc 中的 DemoController
转换为 WebFlux 中的 DemoHandler
:
可以发现,现在的 DemoHandler
已经变成了一个普通类,没有继承也没有实现,除了 @Component
注解外没有任何注解,IOC容器也不知道它到底是什么功能的Bean,也不知道这些方法是不是要转换为实际处理客户端请求的 Handler
。
3.2 新编写RouterConfiguration
因为上面的 DemoHandler
已经没有了 url 映射的功能,需要手动声明路由规则,下面咱编写一个 RouterConfiguration
来配置路由规则(注意这是一个配置类):
可以发现这部分的映射是手动声明的。当然这部分代码可能比较难看懂,因为在上面静态导入了 RequestPredicates
中的所有静态属性和方法。
大概看一眼编写思路:它需要注入前面编写的 DemoHandler
,下面注册一些 RouterFunction
类型的Bean,注册的过程中需要引用 DemoHandler
中的方法,以及配置请求类型、uri、响应类型。
至此,最简单的 WebFlux 使用Demo演示完毕。
4. WebMvc与WebFlux的对比
写到这里,咱先不着急开始走原理,先停下来思考一下,WebMvc 和 WebFlux 有哪些是相同的,又有哪些是不同的呢?
官方文档中有一张图我觉得不错,这里引用一下吧:
这张图很直观的展示出了 WebMvc 和 WebFlux 的兼容功能点,以及各自领域目前特有的功能点。
SpringWebMvc 基于原生 Servlet,所以它是命令式编程,编写相对熟悉,而且很方便调试;Servlet 可以是阻塞的,它更适合跟传统的关系型数据库等阻塞IO的组件进行交互。
SpringWebFlux 基于 Reactor,它是异步非阻塞的,它使用函数式编程,相较于命令式编程和声明式映射更灵活,而且它可以运行在 Netty 上,当然它也可以运行在 Tomcat 、Jetty 、Undertow 等基于 Servlet3.1 规范及以上的Web容器中。
SpringWebMvc 和 SpringWebFlux 都可以使用声明式注解编程来配置控制器和映射路径。
还有一张图,描述的差不多也是这个意思,也就是下面这张图:
【大概了解 WebFlux 的使用之后,下面咱开始解析 WebFlux 中的原理,并且咱希望通过源码分析和原理解读,来从更深的层面来对比 WebMvc和 WebFlux】
最后更新于