Spring WebFlux教程-反应式编程概述

什么是反应式编程(Reactive programming)

维基百科定义:

在计算领域,响应式编程是一种关注数据流和变更传播的声明式编程范式。有了这个范例,就可以轻松地表达静态(例如,数组)或动态(例如,事件发射器)数据流,还可以传递关联执行模型中存在的推断依赖项,这有助于自动传播已更改的数据流。

在一个命令式编程中a:= b + c意味着b+c的结算结果赋值给a,后续b,c值的更改不会影响a的值。在反应式编程中,每当bc的值发生变化时,a的值就会自动更新,而无需程序显式地重新执行语句a:= b + c来重新赋值。

反应式系统特质

反应式宣言 是反应式的理论基础,定义了反应式系统的4个特质:

1. 即时响应性(Responsive)
只要有可能,系统就会及时地做出响应。
2. 回弹性(Resilient)
系统在出现失败时依然保持即时响应性。
3. 弹性(Elastic)
系统在不断变化的工作负载之下依然保持即时响应性。
4. 消息驱动(Message Driven)
反应式系统依赖一步的消息传递,从而确保了松耦合、隔离、位置透明的组件之间有着明确边界。

在这里插入图片描述

反应式流(Reactive Streams)

作为向反应式编程方向迈出的第一步,微软在.NET生态系统中创建了响应式扩展(Rx)库。然后RxJavaJVM上实现了响应式编程。随着时间的推移,通反应式流(Reactive Streams)的努力,Java的标准化出现了,该规范为JVM上的响应式库定义了一组接口和交互规则。它的接口已经集成到Java 9Flow类下。

反应式流Reactive Streams是非阻塞背压异步流处理的规范,包括针对运行时环境(JVMJavaScript)以及网络协议。

目标、设计与适用范围

在异步系统中,处理数据流—尤其是容量没有预先确定的“实时”数据—需要特别注意。最突出的问题是需要控制资源消耗,以便快速数据源不会压倒流目的地。为了在协作网络主机或一台机器中的多个CPU核上并行使用计算资源,需要异步。

Reactive Streams的主要目标是管理跨异步边界的流数据交换—比如将元素传递给另一个线程或线程池—同时确保接收端不会被迫缓冲任意数量的数据。换句话说,背压是该模型的一个组成部分,以便允许在线程之间进行中介的队列被绑定。如果背压的通信是同步的,那么异步处理的好处就会被抵消,因此必须谨慎地强制要求完全非阻塞。

该规范的意图是允许创建许多符合规范的实现,这些实现通过遵守规则将能够顺利地互操作,在流应用程序的整个处理图中保持上述优点和特征。
Reactive Streams 的范围是找到一组最小的接口、方法和协议,这些接口、方法和协议将描述实现目标所需的操作和实体——具有非阻塞背压的异步数据流。

总之,Reactive Streams是JVM上面向流的库的一个标准和规范:

  • 处理一个潜在无限元素的数目
  • 依次处理
  • 异步地在组件之间传递元素
  • 必须强制有非阻塞后压

Reactive Streams规范由以下部分组成:

1、API 规定了需要实现的响应式流类型,并且在不同的实现间完成互操作性。

2、技术兼容套件(TCK)是用于实现一致性测试的标准测试套件。
各种实现可以自由地实现规范中没有提到的额外特性,只要它们遵从API要求和在TCK中通过测试。

API组件

反应式编程范式通常在面向对象语言中作为Observer设计模式的扩展而出现。你还可以将Reactive Streams模式与熟悉的Iterator设计模式进行比较。Iterator模式中Iterable-Iterator总是成对出现,一个主要的区别是,Iterator是基于pull的,而Reactive Streams是基于push的。

使用Iterator是一种命令式编程模式,尽管访问值的方法完全由Iterable负责。实际上,何时访问序列中的next()项取决于开发人员。在反应式流中,上面这一对的等效物是Publisher-Subscriber。但是Publisher在出现新可用值时通知Subscriber,而这个push方面是反应式的关键。

除了push值之外,错误处理和完成方面也以定义良好的方式进行了介绍。Publisher可以向其Subscriber推送新值(通过调用onNext),但也可以发出错误信号(通过调用onError)或完成信号(通过调用onComplete)。错误和完成都终止序列。可以总结如下:

onNext x 0..N [onError | onComplete]

该API由以下组件组成,这些组件必须由Reactive Streams实现提供:

  1. Publisher 发布者
  2. Subscriber 订阅者
  3. Subscription 订阅对象
  4. Processor 处理者

下图展示了订阅者与发布者交互的典型场景:

在这里插入图片描述

接口定义:

//Publisher将数据流发送到 Subscriber
public static interface Publisher<T> {
   //指定订阅者 Subscriber
    public void subscribe(Subscriber<? super T> subscriber);
}
//消费处理 Publisher 发送过来的数据流
public static interface Subscriber<T> {
    //开启订阅Subscription具体的订阅对象
    public void onSubscribe(Subscription subscription);
    //接收数据
    public void onNext(T item);
   //错误处理
    public void onError(Throwable throwable);
   //数据处理结束
    public void onComplete();
}
//订阅对象:发布者和订阅者之间交互的操作对象
public static interface Subscription {
   //订阅者拿到订阅对象后,通过调用订阅对象的request方法,根据自身消费能力请求n条数据
  //request方法被调用时,会触发订阅者的onNext事件方法,把数据传输给订阅者。
//数据全部传输完成,则触发订阅者的onComplete事件方法。如果数据传输发生错误,则触发订阅者的onError事件方法。
    public void request(long n);
   //调用cancel方法来停止接收数据
    public void cancel();
}
//处理者既是发布者又是订阅者,用于发布者和订阅者之间转换数据格式,
//把发布者的T类型数据转换为订阅者接受的R类型数据。处理者作为数据转换的中介不是必须的。
public static interface Processor<T,R> extends Subscriber<T>, Publisher<R> {
}

Java9 Flow

jdk9中的java.util.concurrent.Flow接口1:1语义上等价于对应的Reactive StreamsFlow接口约定了Reactive编程的一套规范,并没有具体的实现。常用的实现有RxJavaReactorAkka等,Spring WebFlux中集成的是Reactor3.0

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

laopeng301

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值