浅谈Spring 5的响应式编程
这篇使用Spring 5进行响应式编程的入门文章展示了你现在可以使用的一些新的non-blocking, asynchronous。感谢优锐课老师给予的指导!
近年来,由于响应式编程能够以声明性的方式(而不是强制性的)构建应用程序,从而在响应程序和弹性方面具有更强的响应能力,因此在开发人员社区和客户中日益流行。Spring 5将Reactive Systems纳入其核心框架的事实表明,范式已向声明式编程转移。
响应式编程管理数据生产者与需要以非阻塞方式对数据做出反应的使用者之间的异步数据流。因此,响应式编程全部与异步和事件驱动的非阻塞应用程序有关,这些应用程序需要少量线程来扩展。
由于基于共享的可变状态,线程和锁扩展应用程序存在很高的复杂性,因此很难使用基于线程的框架来构建反应性应用程序。
在响应式编程上下文中,“一切都是流,并且当流中有数据时,一切都以非阻塞的方式进行。”
为什么响应式编程
响应式编程的高度抽象性提高了代码的可读性,因此开发人员可以主要关注定义业务逻辑的事件的相互依赖性。
反应模式自然适合高度并发环境中的消息处理,这是企业常见的用例。
具有强制背压的功能,响应式方法最适合控制生产者和消费者之间的流量,这将有助于避免内存不足的问题。
响应式编程可以更有效地管理高度互动和实时的应用程序或任何动作/事件可能触发多个连接子系统的通知的情况。
实现响应式编程的理想用例
- 大量交易处理服务,例如银行业。
- 大型在线购物应用程序(例如Amazon)的通知服务。
- 股票交易同时变化的股票交易业务。
响应式流
“响应流”定义了一个API规范,该规范包含一组最少的接口,这些接口公开了用于定义具有非阻塞背压的异步数据流的操作和实体的方法。
引入反压后,反应流允许订户控制发布者的数据交换速率。
Reactive Streams API作为java.util.concurrent.Flow正式成为Java 9的一部分。
响应式流主要用作互操作性层。
Spring 5响应式编程产品
Spring-Web-Reactive模块和Spring MVC都支持相同的@Controller编程,但是Spring-Web-Reactive另外在Reactive和非阻塞引擎上执行。
Spring-Web-Reactive模块和Spring MVC共享许多常用算法,但是Spring-Web-Reactive模块已经重新定义了许多Spring MVC合约,例如HandlerMapping和HandlerAdapter,以使它们异步和非阻塞并启用 反应性HTTP请求和响应(以RouterFunction和HandlerFunction的形式)。
除了现有的RestTemplate之外,Spring 5中还引入了新的反应式WebClient。
支持响应式编程的HTTP客户端(例如Reactor,Netty,Undertow)已经适应了一组响应式的ClientHttpRequest和ClientHttpResponse抽象,这些抽象将请求和响应主体公开为Flux <DataBuffer>,并且在读取和写入端具有完全的反压支持。
Spring 5 Framework引入了Reactor作为Reactive Streams规范的实现。
Reactor是下一代Reactive库,用于在JVM上构建非阻塞应用程序。
Reactor扩展了基本的Reactive Streams Publisher合同,并定义了Flux和Mono API类型,以分别对0..N和0..1的数据序列提供声明性操作。
Spring Web Reactive利用Servlet 3.1提供的非阻塞I / O并在Servlet 3.1容器上运行。
Spring WebFlux提供了两种编程模型的选择。
- 带注释的控制器:这些与Spring MVC相同,带有一些Spring-Web模块提供的附加注释。Spring MVC和WebFlux控制器都支持Reactive返回类型。此外,WebFlux还支持Reactive @RequestBody参数。
- 函数式编程模型:一个基于lambda的轻量级小型库,它公开实用程序来路由和处理请求。
Spring Web响应式与Spring Web MVC
Spring 5彼此相邻容纳了Spring Web Reactive(在spring-web-reactive模块下)和Spring Web MVC(在spring-webmvc模块下)。
尽管Spring Web Reactive和Spring Web MVC模块都共享许多算法,但是由于Spring Web Reactive能够在Reactive和非阻塞的Reactive Streams HTTP适配器层上运行,因此它们不共享代码。
Spring MVC执行需要Servlet容器,而Spring Web Reactive也可以在非Servlet运行时上运行,例如Netty和Undertow。
如果绝对需要带有Java 8 lambda或Kotlin的轻量级功能性Web框架的无阻塞Web堆栈,则应考虑从Spring MVC应用程序切换到Spring Web Reactive。
响应式编程的基本配置
这是带有5.0.0 M5版本和WebFlux依赖项的pom.xml。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.M5</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId> </dependency>
</dependencies>
传统方法与反应方法
在传统方法中,执行将被阻止,并将一直等到服务执行完成。在下面的代码中,在第一个打印语句之后,程序执行将被阻塞并等待服务执行完成。服务执行完成后,将恢复程序执行并执行第二个打印语句。
@GetMapping("/traditional")
public List < Product > getAllProducts() {
System.out.println("Traditional way started");
List < Product > products = prodService.getProducts("traditional");
System.out.println("Traditional way completed");
return products;
}
在响应式方法中,程序将继续执行,而无需等待服务执行的完成。 在下面的代码中,在第一个打印语句之后,第二个打印语句将以非阻塞方式执行,而无需等待服务执行完成。将使用产品数据填充Flux流。
@GetMapping(value = "/reactive", .TEXT_EVENT_STREAM_VALUE)
public Flux < Product > getAll() {
System.out.println("Reactive way using Flux started");
Flux < Product > fluxProducts = prodService.getProductsStream("Flux");
System.out.println("Reactive way using Flux completed");
return fluxProducts;
}
响应式Web客户端
除了现有的RestTemplate之外,Spring 5还引入了Reactive WebClient。
ClientHttpRequest和ClientHttpResponse抽象将请求和响应主体公开为Flux <DataBuffer>,在读取和写入侧具有完全的反压支持。
来自Spring Core的Encoder和Decoder抽象也用于客户端,用于与类型对象之间的字节通量序列化。
以下是一个Reactive WebClient的示例,该示例调用终结点并接收和处理Reactive Stream Flux对象。
@GetMapping("/accounts/{id}/alerts")
public Flux < Alert > getAccountAlerts(@PathVariable Long id) {
WebClient webClient = new WebClient(new ReactorClientHttpConnector());
return this.repository.getAccount(id).flatMap(account -> webClient.perform(get("/alerts/{key}", account.getKey())).extract(bodyStream(Alert.class)));
}
Spring 5的局限性
- 对响应式应用程序进行故障排除有些困难,并且有可能在解决问题时偶然引入了阻止代码。
- 大多数传统的基于Java的集成库仍处于阻塞状态。
- 除少数NoSQL数据库(例如MongoDB)外,Reactive数据存储区提供有限的选项。
- 仍然不支持Spring Security。
感谢阅读!
另外近期整理了一套完整的java架构思维导图,分享给同样正在认真学习的每位朋友~


浅谈Spring 5的响应式编程的更多相关文章
- Spring 5 响应式编程
要点 Reactor 是一个运行在 Java8 之上的响应式流框架,它提供了一组响应式风格的 API 除了个别 API 上的区别,它的原理跟 RxJava 很相似 它是第四代响应式框架,支持操作融合, ...
- springboot2 webflux 响应式编程学习路径
springboot2 已经发布,其中最亮眼的非webflux响应式编程莫属了!响应式的weblfux可以支持高吞吐量,意味着使用相同的资源可以处理更加多的请求,毫无疑问将会成为未来技术的趋势,是必学 ...
- [转帖]浅谈响应式编程(Reactive Programming)
浅谈响应式编程(Reactive Programming) https://www.jianshu.com/p/1765f658200a 例子写的非常好呢. 0.9312018.02.14 21:22 ...
- (转)Spring Boot 2 (十):Spring Boot 中的响应式编程和 WebFlux 入门
http://www.ityouknow.com/springboot/2019/02/12/spring-boot-webflux.html Spring 5.0 中发布了重量级组件 Webflux ...
- Spring Boot 2 (十):Spring Boot 中的响应式编程和 WebFlux 入门
Spring 5.0 中发布了重量级组件 Webflux,拉起了响应式编程的规模使用序幕. WebFlux 使用的场景是异步非阻塞的,使用 Webflux 作为系统解决方案,在大多数场景下可以提高系统 ...
- Spring Boot (十四): 响应式编程以及 Spring Boot Webflux 快速入门
1. 什么是响应式编程 在计算机中,响应式编程或反应式编程(英语:Reactive programming)是一种面向数据流和变化传播的编程范式.这意味着可以在编程语言中很方便地表达静态或动态的数据流 ...
- 响应式编程基础教程:Spring Boot 与 Lettuce 整合
本文主要介绍响应式编程访问 Redis,以及 Spring Boot 与 Lettuce 的整合使用. Lettuce 是可扩展性线程安全的 Redis 客户端,用于同步.异步和响应式使用.如果多个线 ...
- 什么是响应式编程——响应式Spring的道法术器
响应式编程之道 1.1 什么是响应式编程? 在开始讨论响应式编程(Reactive Programming)之前,先来看一个我们经常使用的一款堪称“响应式典范”的强大的生产力工具——电子表格. 举个简 ...
- Reactive(1) 从响应式编程到"好莱坞"
目录 概念 面向流设计 异步化 响应式宣言 参考文档 概念 Reactive Programming(响应式编程)已经不是一个新东西了. 关于 Reactive 其实是一个泛化的概念,由于很抽象,一些 ...
随机推荐
- VS误删sln项目文件怎么办
以项目名为Test为例 打开Test/Test目录下的 Test.vcxproj 文件,试着运行一下,退出后提示保存sln文件,选择一个目录即可.
- 树莓派安装nextcloud、Seafile
参考博文:http://bbs.eeworld.com.cn/thread-505579-1-1.html http://blog.sina.com.cn/s/blog_6f55d8210102xia ...
- C++常量表达式、const、constexpr(C++11新增)的区别
常量表达式是指值不会改变且在编译过程中就能够得到计算结果的表达式,能在编译时求值的表达式. 程序先编译再运行: 在编译阶段, 编译器将在编译过程中把用到该常量的地方都全都替换为 常量的值. 但是常量 ...
- Python基础-2 变量与常量
变量与常量 变量:在程序运行过程中,值会发生变化的量 常量:在程序运行过程中,值不会发生变化的量 无论是变量还是常量,在创建时都会在内存中开辟一块空间,用于保存它的值. 这里有一点需要注意的是,在py ...
- Fiddler抓包(基本使用方法、web+app端抓包、篡改数据、模拟低速)
1.HTTP代理原理图 http服务器代理:既是web服务器,又是web客户端 接口vs端口: 接口:包含地址和端口 端口:类似于USB接口 地址:127.0.0.1,端口默认:8888 ...
- 引入CSS的方式、link和@import的区别
引入CSS的方式有四种:内联方式.嵌入方式.链接方式.导入方式. 内联方式 内联方式指的是直接在 HTML 标签中的 style 属性中添加 CSS. <div style="back ...
- How to add VTL tapes on DD6300 & label them into "Oracle_VTL" pool
Dear all , This is liulei , I was back so , How to add VTL tapes on DD6300 & label them into ...
- 常见Http状态码大全详解
HTTP状态码的分类 HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用.HTTP状态码共分为5种类型: 具体如下: 状态码 内容 详细内容 信息告知 - ...
- Python 之网络编程之socket(2)黏包现象和socketserver并发
一:黏包 ###tcp协议在发送数据时,会出现黏包现象. (1)数据粘包是因为在客户端/服务器端都会有一个数据缓冲区, 缓冲区用来临时保存数据,为了保证能够完整的接收到数据,因此缓冲区 ...
- day11-Python运维开发基础(迭代器与可迭代对象、高阶函数)
1. 迭代器与可迭代对象 # ### 迭代器 """ 迭代器: 能被next方法调用,并且不断返回下一个值的对象,是迭代器(对象) 特征:迭代器会生成惰性序列,它通过计算 ...