目录
一, 什么是 Spring webFlux
二, WebFlux 的优势 & 性能
三, WebFlux 应用场景
四, 适用性
五, 快速入门
5.1 添加 webflux 依赖
5.2 定义接口
5.3 测试接口
六, 总结
七, GitHub 示例代码
一, 什么是 Spring WebFlux
下图截自 Spring Boot 官方网站:
结合上图, 在了解 Spring WebFlux 之前, 我们先来对比说说什么是 Spring MVC, 这更有益我们去理解 WebFlux, 图右边对 Spring MVC 的定义, 原文如下:
Spring MVC is built on the Servlet API and uses a synchronous blocking I/O architecture whth a one-request-per-thread model.
翻译一下, 意思如下:
Spring MVC 构建于 Servlet API 之上, 使用的是同步阻塞式 I/O 模型, 什么是同步阻塞式 I/O 模型呢? 就是说, 每一个请求对应一个线程去处理.
了解了 Spring MVC 之后, 再来说说 Spring WebFlux:
上图左边, 官方给出的定义如下:
Spring WebFlux is a non-blocking Web framework built from the ground up to take advantage of multi-core, next-generation processors and handle massive numbers of concurrent connections.
翻译一下, 内容如下:
Spring WebFlux 是一个异步非阻塞式的 Web 框架, 它能够充分利用多核 CPU 的硬件资源去处理大量的并发请求.
二, WebFlux 的优势 & 性能
WebFlux 内部使用的是响应式编程 (Reactive Programming), 以 Reactor 库为基础, 基于异步和事件驱动, 可以让我们在不扩充硬件资源的前提下, 提升系统的吞吐量和伸缩性.
看到这里, 你是不是以为 WebFlux 能够使程序运行的更快呢? 比如说使用 WebFlux 以后, 一个接口的请求响应时间是不是就缩短了呢?
答案是否定的! 以下是官方原话:
Reactive and non-blocking generally do not make applications run faster.
WebFlux 并不能使接口的响应时间缩短, 它仅仅能够提升吞吐量和伸缩性.
三, WebFlux 应用场景
上面说到了, Spring WebFlux 是一个异步非阻塞式的 Web 框架, 所以, 它特别适合应用在 IO 密集型的服务中, 比如微服务网关这样的应用中.
PS: IO 密集型包括: 磁盘 IO 密集型, 网络 IO 密集型, 微服务网关就属于网络 IO 密集型, 使用异步非阻塞式编程模型, 能够显著地提升网关对下游服务转发的吞吐量.
四, 适用性
从上图中, 可以一眼看出 Spring MVC 和 Spring WebFlux 的相同点和不同点:
相同点:
都可以使用 Spring MVC 注解, 如 @Controller, 方便我们在两个 Web 框架中自由转换;
均可以使用 Tomcat, Jetty, Undertow Servlet 容器;
...
注意点:
Spring MVC 因为是使用的同步阻塞式, 更方便开发人员编写功能代码, Debug 测试等, 一般来说, 如果 Spring MVC 能够满足的场景, 就尽量不要用 WebFlux, 因为转向非阻塞响应式编程学习曲线是陡峭的, 小组成员的学习成本要考量进来;
WebFlux 默认情况下使用 Netty 作为服务器;
在微服务架构中, Spring MVC 和 WebFlux 可以混合使用, 比如, 对于那些 IO 密集型服务 (如网关), 我们就可以使用 WebFlux 来实现.
五, 快速入门
5.1 添加 webflux 依赖
新建一个 Spring Boot 项目, 新建步骤可参考笔者另一篇博文《Spring Boot 入门教程 | 图文讲解》 https://www.exception.site/springboot , 在 pom.xml 文件中添加 webflux 依赖:
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-webflux</artifactId>
- </dependency>
5.2 定义接口
新建一个 controller 包, 用来放置对外的接口类, 再创建一个 HelloWebFluxController.class 类, 定义两个接口:
- package site.exception.springbootwebfluxhello.controller;
- import org.springframework.Web.bind.annotation.GetMapping;
- import org.springframework.Web.bind.annotation.RestController;
- import reactor.core.publisher.Mono;
- import site.exception.springbootwebfluxhello.entity.User;
- /**
- * @author 犬小哈 (微信号: 小哈学 Java)
- * @site 个人网站: www.exception.site
- * @date 2019/4/15
- * @time 下午 9:12
- * @discription
- **/
- @RestController
- public class HelloWebFluxController {
- @GetMapping("/hello")
- public String hello() {
- return "Hello, WebFlux !";
- }
- @GetMapping("/user")
- public Mono<User> getUser() {
- User user = new User();
- user.setName("犬小哈");
- user.setDesc("欢迎关注我的公众号: 小哈学 Java");
- return Mono.just(user);
- }
- }
- User.java:
- package site.exception.springbootwebfluxhello.entity;
- /**
- * @author 犬小哈 (微信号: 小哈学 Java)
- * @site 个人网站: www.exception.site
- * @date 2019/4/15
- * @time 下午 9:12
- * @discription
- **/
- public class User {
- /**
- * 姓名
- */
- private String name;
- /**
- * 描述
- */
- private String desc;
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getDesc() {
- return desc;
- }
- public void setDesc(String desc) {
- this.desc = desc;
- }
- }
以上控制器类中, 我们使用的全都是 Spring MVC 的注解, 分别定义了两个接口:
一个 GET 请求的 /hello 接口, 返回 Hello, WebFlux ! 字符串.
又定义了一个 GET 请求的 /user 方法, 返回的是 JSON 格式 User 对象.
这里注意, User 对象是通过 Mono 对象包装的, 你可能会问, 为啥不直接返回呢?
在 WebFlux 中, Mono 是非阻塞的写法, 只有这样, 你才能发挥 WebFlux 非阻塞 + 异步的特性.
补充: 在 WebFlux 中, 除了 Mono 外, 还有一个 Flux, 这哥俩均能充当响应式编程中发布者的角色, 不同的是:
Mono: 返回 0 或 1 个元素, 即单个对象.
Flux: 返回 N 个元素, 即 List 列表对象.
5.3 测试接口
启动项目, 查看控制台输出:
当控制台中输出中包含 Netty started on port(s): 8080 语句时, 说明默认使用 Netty 服务已经启动了.
打开浏览器, 先对 /user 接口发起调用:
返回成功.
再来对 /user 接口测试一下:
返回 JSON 格式的 User 实体也是 OK 的!
六, 总结
本文中, 我们学习了什么是 Spring WebFlux, 以及 WebFlux 的优势和应用场景, 接下来我么将 WebFlux 与 Spring MVC 做了一下适用性比较, 最后上手操作写了两个简单的接口, 并测试成功了.
下一章中, 我们将进一步学习, 如何在 WebFlux 中对数据库做增删改查操作, 敬请期待吧!
七, GitHub 示例代码
八, Ref
https://spring.io/
赠送 | 面试 & 学习福利资源
最近在网上发现一个不错的 PDF 资源《Java 核心面试知识. PDF》分享给大家, 不光是面试, 学习, 你都值得拥有!!!
获取方式: 关注公众号: 小哈学 Java, 后台回复 资源, 既可获取资源链接, 下面是目录以及部分截图:
重要的事情说两遍, 获取方式: 关注公众号: 小哈学 Java, 后台回复 资源, 既可获取资源链接 !!!
来源: https://www.cnblogs.com/quanxiaoha/p/10713782.html