0009 - WebFlux
1、概述
大多数场景使用MVC都是阻塞式的,WebFlux使用的场景是异步非阻塞的
响应式编程是基于异步和事件驱动的非阻塞程序,只是垂直通过在JVM内启动少量线程扩展,而不是水平通过集群扩展。
Spring Boot2.x 包含了一个新的spring-webflux模块,该模块包含对响应式HTTP和webSocket交互等程序的支持。
2、优势
- 微服务架构越来越火,Spring Boot是一大趋势,所以Spring Cloud是基于Spring Boot的,所以学好Spring Boot WebFlux会受益匪浅
- 从编程来讲,虽然阻塞式编程是避免不了的,但是Reactive编程在大多数场景,能够提高资源利用率。所以,学习WebFlux,尤其某些IO密集型场景很刚需
3、前置概念
3.1、Reactive Streams(响应式流) JVM中面向流库标准和规范
- 处理可能午线数量的元素
- 按顺序处理
- 组件之间异步传递
- 强制性非阻塞背压
一般由以下组成
- 发布者:发布元素到订阅者
- 订阅者:消费元素
- 订阅:在发布者中,订阅被创建时,将与订阅者共享
- 处理器:发布者和订阅者之间的处理数据
3.2、Backpressure 背压
背压是一种常用策略,使得发布者拥有无限制的缓冲区存储元素,用于确保发布者发布元素太快时,不会去压制订阅者。
4、响应式编程
有了ReactiveStreams这种标准和规范,利用规范可以进行响应式编程。那再了解下什么是ReactiveProgramming响应式编程。响应式编程是基于异步和事件驱动的非阻塞程序,只是垂直通过再JVM内启动少量线程扩展,而不是水平通过集团扩展。这就是一个编程范例,具体项目中如何体现呢?
响应式项目编程实战中,通过基于Reactive Streams规范实现的框架Reactor去实战。Reactor一共提供两种响应式API:
- Mono:实现发布者,并返回0或1个元素
- Flux:实现发布者,并返回N个元素
Spring Boot WebFlux就是基于Reactor实现的。Spring Boot 2.0包括一个新的spring-webflux模块。该模块包含对响应式HTTP和WebSocket客户端的支持,以及对REST,HTML和WebSocket交互式程序的支持。一般来说,SpringMVC用于同步处理,Spring WebFlux用于异步处理。
Spring Boot WebFlux由两种编程方式,一种类似Spring MVC注解方式,另一种是使用其功能性端点方式
5、特性
- 响应式API
Reactor框架是Spring Boot WebFlux响应库依赖,通过Reactive Streams并与其他响应库交互。提供 两种响应式API:Mono、Flux。一般是将Publisher作为输入,在框架内部转换成Reactor类型并处理逻辑,然后返回Flux和Mono作为输出。
- 编程模型
Spring 5 Web模块包含了Spring webFlux的HTTP抽象。类似Servlet API,WebFlux提供WebHandler API去定义非阻塞API抽象接口。可以选择以下两种编程模型实现。
- 注解控制层:和Spring MVC 保持一致,WebFlux也支持响应式@RequestBody注解。
- 功能性端点:基于Lambda轻量级编程模型,用来路由和处理清楚的小工具。和上面最大的区别就是,这种模型,全程控制了请求-响应的生命流程。
- 适用性
一图就很明确了,WebFlux 和 MVC 有交集,方便大家迁移。但是注意:
MVC 能满足场景的,就不需要更改为 WebFlux。
要注意容器的支持,可以看看下面内嵌容器的支持。
微服务体系结构,WebFlux 和 MVC 可以混合使用。尤其开发 IO 密集型服务的时候,选择 WebFlux 去实现。
- 内嵌容器
跟Spring Boot大框架一样启动应用,但WebFlux默认是通过Netty启动,并且自动设置了默认端口为8080.另外还提供了对Jetty、Undertow等容器的支持。开发者自行在添加对应的容器Starter组件依赖,即可配置并使用对应内嵌容器实例。
- Starter组件
Spring Boot WebFlux提供了很多“开箱即用”的Starter组件。Starter组件是被加载在应用中的Maven依赖项。只需要在Maven配置中添加对应的依赖配置,即可使用对应的Starter组件,例如:添加spring-boot-starter-webflux依赖,就可以用于构建响应式API服务,其包含了Web Flux和Tomcat内嵌容易等。
6、组件
Spring Boot WebFlux官方提供了很多的Starter组件,每一个模块会有多种技术实现选型支持,来实现各种复杂的业务需求
- web:spring WebFlux
- 模板引擎:Thymeleaf
- 存储:Redis、MongoDB、Cassandra
- 内嵌容器:Tomcat、Jetty、Undertow
7、HelloWorld
7.1、新建maven 工程,配置POM依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
spring-boot-starter-webflux 依赖,是我们核心需要学习 webflux 的包,里面默认包含了 spring-boot-starter-reactor-netty 、spring 5 webflux 包。也就是说默认是通过 netty 启动的。
reactor-test、spring-boot-starter-test 两个依赖搭配是用于单元测试。
spring-boot-maven-plugin 是 Spring Boot Maven 插件,可以运行、编译等调用。
7.2、编写处理器类 Handler
新建包 org.spring.springboot.handler ,作为编写功能处理类。新建城市(City)例子的处理类 CityHandler,代码如下:
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
@Component
public class CityHandler {
public Mono<ServerResponse> helloCity(ServerRequest request) {
return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN)
.body(BodyInserters.fromObject("Hello, City!"));
}
}
ServerResponse 是对响应的封装,可以设置响应状态,响应头,响应正文。比如 ok 代表的是 200 响应码、MediaType 枚举是代表这文本内容类型、返回的是 String 的对象。
这里用 Mono 作为返回对象,是因为返回包含了一个 ServerResponse 对象,而不是多个元素。
7.3、编写路由器类 Router
新建 org.spring.springboot.router 包,作为编写路由器类。新建城市(City)例子的路由类 CityRouter,代码如下:
import org.spring.springboot.handler.CityHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
@Configuration
public class CityRouter {
@Bean
public RouterFunction<ServerResponse> routeCity(CityHandler cityHandler) {
return RouterFunctions
.route(RequestPredicates.GET("/hello")
.and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),
cityHandler::helloCity);
}
}
RouterFunctions 对请求路由处理类,即将请求路由到处理器。这里将一个 GET 请求 /hello 路由到处理器 cityHandler 的 helloCity 方法上。跟 Spring MVC 模式下的 HandleMapping 的作用类似。
RouterFunctions.route(RequestPredicate, HandlerFunction) 方法,对应的入参是请求参数和处理函数,如果请求匹配,就调用对应的处理器函数。
7.4、启动运行项目 ,输入http://localhost:8080/hello
0009 - WebFlux的更多相关文章
- springboot2 webflux 响应式编程学习路径
springboot2 已经发布,其中最亮眼的非webflux响应式编程莫属了!响应式的weblfux可以支持高吞吐量,意味着使用相同的资源可以处理更加多的请求,毫无疑问将会成为未来技术的趋势,是必学 ...
- Spring Webflux: Kotlin DSL [片断]
原文链接:https://dzone.com/articles/spring-webflux-kotlin-dsl-snippets 作者:Biju Kunjummen 译者:Jackie Tang ...
- 一文带你了解 Spring 5.0 WebFlux 应用场景
一.什么是 Spring WebFlux 下图截自 Spring Boot 官方网站: 结合上图,在了解 Spring WebFlux 之前,我们先来对比说说什么是 Spring MVC,这更有益我们 ...
- Spring Boot 2.0 WebFlux 教程 (一) | 入门篇
目录 一.什么是 Spring WebFlux 二.WebFlux 的优势&提升性能? 三.WebFlux 应用场景 四.选 WebFlux 还是 Spring MVC? 五.异同点 六.简单 ...
- Spring WebFlux开门迎客,却来了一位特殊客人
话说Spring WebFlux已经出现有一段时间了,但是知道他的人并不是很多.这让他很是闷闷不乐. 还有更惨的是,那些敢于吃螃蟹的人在尝试了他之后,有的竟把代码重新改回到Spring MVC的同步模 ...
- Spring Boot 2.x 系列教程:WebFlux 系列教程大纲(一)
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! WebFlux 系列教程大纲 一.背景 大家都知道,Sprin ...
- Spring Boot 2.x 系列教程:WebFlux REST API 全局异常处理 Error Handling
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 本文内容 为什么要全局异常处理? WebFlux REST 全 ...
- 爸爸又给Spring MVC生了个弟弟叫Spring WebFlux
情景引入 很早之前,Java就火起来了,是因为它善于开发和处理网络方面的应用. Java有一个爱好,就是喜欢制定规范标准,但自己又不善于去实现. 反倒是一些服务提供商使用它的规范标准来制造应用服务器而 ...
- Spring WebFlux 响应式编程学习笔记(一)
各位Javaer们,大家都在用SpringMVC吧?当我们不亦乐乎的用着SpringMVC框架的时候,Spring5.x又悄(da)无(zhang)声(qi)息(gu)的推出了Spring WebFl ...
随机推荐
- python基础(六)——mysql的使用
//验证是否安装mysqldb,这个是用于python连接mysql数据库的接口,而不是我们平时用的mysql import MySQLdb 安装MySQLdb,请访问 http://sourcefo ...
- 06机器学习实战之SVM
对偶的概念 https://blog.csdn.net/qq_34531825/article/details/52872819?locationNum=7&fps=1 拉格朗日乘子法.KKT ...
- C# to IL 6 Reference and Value Types(引用类型和值类型)
An interface is a reference type, in spite of the fact that it has no code at all. Thus, wecannot in ...
- JDK8新增时间类型用在JPA中的问题
之前数据库存储日期时间类型时一般POJO实体对应属性为java.util.Date,然后通过JPA注解指定它是日期格式或是日期时间格式,JDK8中新增了更好的时间API,如表示本地日期的LocalDa ...
- 【转存】Vue组件选项props
原帖地址 前面的话 组件接受的选项大部分与Vue实例一样,而选项props是组件中非常重要的一个选项.在 Vue 中,父子组件的关系可以总结为 props down, events up.父组件通过 ...
- node inspector
- c#多线程与委托(转)
一:线程在.net中提供了两种启动线程的方式,一种是不带参数的启动方式,另一种是带参数的启动的方式.不带参数的启动方式 如果启动参数时无需其它额外的信息,可以使用ThreadStart来实例化Thre ...
- insert into on duplicate key update
问题 有一个表,建表语句如下: CREATE TABLE `tbl_host` ( `id` bigint(64) NOT NULL AUTO_INCREMENT, `ip` varchar(255) ...
- Eclipse各个版本及其对应代号、下载地址列表
版本号 代码 日期 下载地址 Eclipse 3.1 IO[木卫一,伊奥] 2005 http://archive.eclipse.org/eclipse/downloads/drops/R-3.1- ...
- phpmailer使用qq邮箱、163邮箱成功发送邮件实例代码
以前使用qq邮箱.163服务器发送邮件,帐号直接使用密码,现在不行了,得使用授权码,简单记录下 1.首先开通POP3/SMTP服务,qq邮箱——帐号——设置,找到POP3/SMTP点开启,输入短信会有 ...