浅谈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 其实是一个泛化的概念,由于很抽象,一些 ...
随机推荐
- c++继承:公有、私有、保护(对应p12访问限制)
公有继承(public).私有继承(private).保护继承(protected)是常用的三种继承方式. 1. 公有继承(public) 公有继承的特点是基类的公有成员和保护成员作为派生类的成员时, ...
- 时间和日期实例-<Calender计算出生日期相差几天>
String day1="1994:10:04"; String day2="1994:10:03"; SimpleDateFormat format= new ...
- 【转】 android之如何在两个activity之间传递handler_利用broadcast广播机制
原文:http://blog.csdn.net/jason0539/article/details/18075293 这算是如何在两个activity之间传递handler的解决方案二了,解决方案一见 ...
- js 实现复制功能
//复制注册地址 function copyTuiJianAddress() { try { var name = document.getElementById("share") ...
- SpringMVC配置没有任何问题根据请求却怎么都找不到映射(tomcat所导致的问题)
本人在做SpringMVC练习的时候,配置文件反复检查了不下十几遍,没有任何问题,然后就招了个之前的项目的源码复制进去,原来的项目没有任何问题,这个项目却怎么都不能跳转路径,然后有找了一个Spring ...
- 郁闷的 IE6/7/8 所遇兼容问题
IE6,7只支持inline元素设置为inline-block,但不支持block元素转换成inline-block,所以非inline元素在IE6,7下要转换成inline-block,需先转换成i ...
- 设计模式课程 设计模式精讲 15-2 桥接模式Coding
1 代码演练 1.1 代码演练1 1.2 代码演练2 1 代码演练 1.1 代码演练1 需求: 打印出从银行获取的账号类 优点: a 假如我只用用一个银行接口 去获取账号的内容,银行实现类要有定期 ...
- Python 操作rabbitmq中的confirm模式的错误
今天使用rabbitmq的confirm模式,书上介绍的是pika版本是0.9.6,但是我用的是别的版本,发现这样的错误 Traceback (most recent call last): Fil ...
- LibreOJ #6001. 「网络流 24 题」太空飞行计划
\(\quad\) 与网络流有关的最值有三个:最大流,最小费用,最小割.这道题是最小割.想了好久,终于想明白最小割应该怎么用. \(\quad\) 先找出矛盾的事物.在这道题中,两件事是矛盾的:做实验 ...
- 多个span标签在同一行显示
属性设置为display:inline或display:inline-block