一、什么是 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 密集型,使用异步非阻塞式编程模型,能够显著地提升网关对下游服务转发的吞吐量。

四、选 WebFlux 还是 Spring MVC?

首先你需要明确一点就是:WebFlux 不是 Spring MVC 的替代方案!,虽然 WebFlux 也可以被运行在 Servlet 容器上(需是 Servlet 3.1+ 以上的容器),但是 WebFlux 主要还是应用在异步非阻塞编程模型,而 Spring MVC 是同步阻塞的,如果你目前在 Spring MVC 框架中大量使用非同步方案,那么,WebFlux 才是你想要的,否则,使用 Spring MVC 才是你的首选。

在微服务架构中,Spring MVC 和 WebFlux 可以混合使用,比如已经提到的,对于那些 IO 密集型服务(如网关),我们就可以使用 WebFlux 来实现。

选 WebFlux 还是 Spring MVC? This is not a problem!

咱不能为了装逼而装逼,为了技术而技术,还要考量到转向非阻塞响应式编程学习曲线是陡峭的,小组成员的学习成本等诸多因素。

总之一句话,在合适的场景中,选型最合适的技术

五、异同点

从上图中,可以一眼看出 Spring MVC 和 Spring WebFlux 的相同点和不同点:

相同点:

  • 都可以使用 Spring MVC 注解,如 @Controller, 方便我们在两个 Web 框架中自由转换;
  • 均可以使用 Tomcat, Jetty, Undertow Servlet 容器(Servlet 3.1+);
  • ...

注意点:

  • Spring MVC 因为是使用的同步阻塞式,更方便开发人员编写功能代码,Debug 测试等,一般来说,如果 Spring MVC 能够满足的场景,就尽量不要用 WebFlux;
  • WebFlux 默认情况下使用 Netty 作为服务器;
  • WebFlux 不支持 MySql;

六、简单看看 WebFlux 是如何分发请求的

使用过 Spring MVC 的小伙伴们,应该到知道 Spring MVC 的前端控制器是 DispatcherServlet, 而 WebFlux 是 DispatcherHandler,它实现了 WebHandler 接口:

来看看DispatcherHandler类中处理请求的 handle 方法:

  • ①:ServerWebExchange 对象中放置每一次 HTTP 请求响应信息,包括参数等;
  • ②:判断整个接口映射 mappings 集合是否为空,空则创建一个 Not Found 的错误;
  • ③:根据具体的请求地址获取对应的 handlerMapping;
  • ④:调用具体业务方法,也就是我们定义的接口方法;
  • ⑤:处理返回的结果;

七、快速入门

7.1 添加 webflux 依赖

新建一个 Spring Boot 项目,新建步骤可参考笔者另一篇博文《Spring Boot 入门教程 | 图文讲解》,在 pom.xml 文件中添加 webflux 依赖:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

7.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 列表对象。

7.3 测试接口

启动项目,查看控制台输出:

当控制台中输出中包含 Netty started on port(s): 8080 语句时,说明默认使用 Netty 服务已经启动了。

打开浏览器,先对 /user 接口发起调用:

返回成功。

再来对 /user 接口测试一下:

返回 JSON 格式的 User 实体也是 OK 的!

八、总结

本文中,我们学习了什么是 Spring WebFlux, WebFlux 的优势和应用场景,接下来我么谈了谈在我们生产环境中技术选型该选 WebFlux 还是 Spring MVC, 两者之间又有什么异同点,以及从源码角度了解了 WebFlux 是如何分发请求的。

最后上手操作写了两个简单的接口,并测试成功了。

下一章中,我们将进一步学习,如何在 WebFlux 中对数据库做增删改查操作,敬请期待吧!

九、GitHub 示例代码

https://github.com/weiwosuoai/spring-boot-tutorial/tree/master/spring-boot-webflux-hello

十、Ref

赠送 | 面试&学习福利资源

最近在网上发现一个不错的 PDF 资源《Java 核心知识&面试.pdf》分享给大家,不光是面试,学习,你都值得拥有!!!

获取方式: 关注公众号: 小哈学Java, 后台回复 资源,既可免费无套路获取资源链接,下面是目录以及部分截图:

重要的事情说两遍,关注公众号: 小哈学Java, 后台回复 资源,既可免费无套路获取资源链接 !!!

欢迎关注微信公众号: 小哈学Java

一文带你了解 Spring 5.0 WebFlux 应用场景的更多相关文章

  1. 一文带你认识Spring事务

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y Spring事务管理我相信大家都用得很多,但可能仅仅 ...

  2. 一文带你深入浅出Spring 事务原理

    Spring事务的基本原理 Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的.对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行: 获 ...

  3. 一文带你了解Spring核心接口Ordered的实现及应用

    前言 最近在看框架的时候,发现了这个接口,在此进行总结,希望能够给大家帮助,同时提升自己. order接口的大体介绍 Spring框架中有这个一个接口,名字叫Ordered,联想我们在数据库中应用的O ...

  4. 一文带你掌握Spring Web异常处理方式

    一.前言 大家好,我是 去哪里吃鱼 ,也叫小张. 最近从单位离职了,离开了五年多来朝朝夕夕皆灯火辉煌的某网,激情也好悲凉也罢,觥筹场上屡屡物是人非,调转过事业部以为能换种情绪,岂料和下了周五的班的前同 ...

  5. 【项目实践】一文带你搞定Spring Security + JWT

    以项目驱动学习,以实践检验真知 前言 关于认证和授权,R之前已经写了两篇文章: [项目实践]在用安全框架前,我想先让你手撸一个登陆认证 [项目实践]一文带你搞定页面权限.按钮权限以及数据权限 在这两篇 ...

  6. JDBC、ORM、JPA、Spring Data JPA,傻傻分不清楚?一文带你厘清个中曲直,给你个选择SpringDataJPA的理由!

    序言 Spring Data JPA作为Spring Data中对于关系型数据库支持的一种框架技术,属于ORM的一种,通过得当的使用,可以大大简化开发过程中对于数据操作的复杂度. 本文档隶属于< ...

  7. 从源码入手,一文带你读懂Spring AOP面向切面编程

    之前<零基础带你看Spring源码--IOC控制反转>详细讲了Spring容器的初始化和加载的原理,后面<你真的完全了解Java动态代理吗?看这篇就够了>介绍了下JDK的动态代 ...

  8. 详解 Spring 3.0 基于 Annotation 的依赖注入实现(转)

    使用 @Repository.@Service.@Controller 和 @Component 将类标识为 Bean Spring 自 2.0 版本开始,陆续引入了一些注解用于简化 Spring 的 ...

  9. 使用spring 4.0 + maven 构建超简单的web项目

    一.需求 使用spring去管理web项目,是目前非常流行的一种思路,本文将介绍使用maven+spring 4.0.2 来构建一个简单的web项目. 二.实现 1.新建一个maven项目,如下图所示 ...

随机推荐

  1. linux常用命令合集(未完)

    (1)新建 新建文件夹:mkdir 文件夹名 新建文件:touch 文件路径/文件名 删除: rm –f filename删除文件 rm –rf filename删除文件夹 (2)重命名 1将一个名为 ...

  2. Hibernate JPA 动态criteria语句针对null查询条件的特殊处理

    最近原Hibernate项目需要添加一个条件,结构有点类似下面的格式,学生和房间是多对一的关系,现在要查询所有没有房间的学生. Class Student{ @ManyToOne Room room; ...

  3. IDEA 的maven项目打jar 编写UDF 在hive端运行 (全过程,有录制的操作视频)

    一.       前提准备 服务端hive搭建完成,可以正常创建访问表 本地端使用的IDE是Intellij IDEA(我的是2017版本,老版本需要支持创建maven项目) ,并且电脑有网. 二.  ...

  4. ArrayList源码分析超详细

    ArrayList源码分析超详解 想要分析下源码是件好事,但是如何去进行分析呢?以我的例子来说,我进行源码分析的过程如下几步: 找到类:利用 IDEA 找到所需要分析的类(ztrl+N查找ArraLi ...

  5. 前端开发APP,从HBuilder开始~ 【转】

    内容简介 介绍目前前端人员开发app的几种方法,具体介绍hbuilder开发app,一扇赞新的大门~ 无所不能的js 最开始js仅仅局限于网页上一些效果,操作网页内容等, 但是nodejs把js带入了 ...

  6. scrapy安装过程问题解决、新建项目、调试断点

    一.安装问题 1. 下载速度太慢 使用国外源,下载速度很慢,可以考虑使用豆瓣的镜像下载 pip install -i https://pypi.douban.com/simple/ scrapy 2. ...

  7. 用shell处理以下内容 1、按单词出现频率降序排序! 2、按字母出现频率降序排序! the squid project provides a number of resources toassist users design,implement and support squid installations. Please browsethe documentation and support

    此题目有多种解法,sed.awk.tr等等,都可以解决此题,命令运用灵活多变. 编写shell脚本no_20.sh 解法1: #!/bin/bash ###-------------CopyRight ...

  8. FPA笔记三 数据功能的识别

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://welkinhu.blog.51cto.com/447606/115477     ...

  9. 计算器源码(数学式python)

    ''' ******************** 请计算表达式: 1 - 2 * ( (60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/1 ...

  10. jQuery-01:on live bind delegate

    摘自:https://www.cnblogs.com/moonreplace/archive/2012/10/09/2717136.html moonreplace这位大牛的 当我们试图绑定一些事件到 ...