【MVC】Spring WebFlux
一、什么是 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
接口发起调用:
返回成功。
转自:https://www.cnblogs.com/quanxiaoha/p/10773773.html
【MVC】Spring WebFlux的更多相关文章
- 【MVC】Spring MVC常用配置
一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于SpringMVC的配置 <!--conf ...
- 【Web】Spring WebFlux
阅读目录 一.关于WebFlux 二.SpringMVC与SpringWebFlux 三.Reactive Spring Web 四.实现WebFlux示例 SpringWebflux是SpringF ...
- 【转】Spring学习---Spring IoC容器的核心原理
[原文] Spring的两个核心概念:IoC和AOP的雏形,Spring的历史变迁和如今的生态帝国. IoC和DI的基本概念 IoC(控制反转,英文含义:Inverse of Control)是Spr ...
- 【原】Spring整合Redis(第二篇)—SDR环境搭建具体步骤
[环境参数] Spring版本:4.2.6.RELEASESpring-Data-Redis版本:1.7.2.RELEASE Redis版本:redis-2.4.5-win32-win64 [简要说明 ...
- 【目录】Spring 源码学习
[目录]Spring 源码学习 jwfy 关注 2018.01.31 19:57* 字数 896 阅读 152评论 0喜欢 9 用来记录自己学习spring源码的一些心得和体会以及相关功能的实现原理, ...
- 【MVC】ASP.NET MVC Forms验证机制
http://www.cnblogs.com/bomo/p/3309766.html 随笔 - 121 文章 - 0 评论 - 92 [MVC]ASP.NET MVC Forms验证机制 ASP. ...
- 【MVC】 js,css 压缩
[MVC] js,css 压缩 一. 引用 System.Web.Optimization.dll : 使用 Nuget ,在控制台输入 Install-Package Microsoft.AspNe ...
- 【MVC】 异常处理
[MVC] 异常处理 一 . 自定义 HandleErrorAttribute public class ExceptionLogAttribute : HandleErrorAttribute { ...
- 【MVC】 非常简单的页面导出 WORD, EXCEL方法
[MVC] 页面导出 WORD, EXCEL 前端 js function output() { var para = new Object(); para.html = getHtml(" ...
随机推荐
- 【leetcode】1012. Complement of Base 10 Integer
题目如下: Every non-negative integer N has a binary representation. For example, 5 can be represented a ...
- vue-葵花宝典
router-view 中包含 router-view 这种情况就可以 使用嵌套路由了 变化的视图中包含变化的视图 代码层面 router-view 中 包含router-view 路由childre ...
- 2.Javascript 函数(主要)
定义函数 在JavaScript中,定义函数的方式如下: function abs(x) { if (x >= 0) { return x; } else { return -x; } } 上述 ...
- 大量TIME_WAIT连接的解决办法
1.使用keep alive连接(待补充) 2.修改tcp参数 根据TCP协议的连接断开规定,发起socket主动关闭的一方,socket将进入TIME_WAIT状态,TIME_WAIT状态将持续2个 ...
- CMMI模型
CMMI的成熟度级别 初始级(过程不可预测,管理和控制差,是反应式的)管理级(过程处于项目级,经常是反应式的)定义级(过程已经提升到组织级(OSSP))定量管理级(对过程进行度量,并进行统计控制)优化 ...
- 2018-2019 ACM-ICPC Brazil Subregional Programming Contest F. Music Festival
题目:https://codeforces.com/gym/101908/problem/F 题意:给你n个舞台,每个舞台有很多个节目,每个节目有个开始时间,结束时间,价值,每个舞台至少出演过一个节目 ...
- (66) c# async await
1.使用 async await 2.返回值 static void Main(string[] args) { Program p = new Program(); Console.WriteLin ...
- 116、TensorFlow变量的版本
import tensorflow as tf v = tf.get_variable("v", shape=(), initializer=tf.zeros_initialize ...
- Zlib not installed
若提示:zlib not installed wget http://zlib.net/zlib-1.2.8.tar.gz tar zxf zlib-1.2.8.tar.gz cd zlib- ...
- Linux操作系统(二)_快速入门
环境 安装VM ware,输入VM key 在VM上安装CentOS 6.5 设置网络,能在本机上ping通 通过终端连接工具:Xshell或SecureCRT,连接Linux服务器 实操可能出现的问 ...