高级特性与概念
本章介绍 Reactor 的高级特性与概念,包括以下内容:
本节小结
📄️ 复用操作符用法
从整洁代码的角度来看,代码复用通常是一件好事。 Reactor 提供了若干模式,可以帮助您复用和共用代码,尤其是那些您可能想在代码库中反复使用的操作符或操作符组合。如果把一条操作符链想象成一份菜谱,您就可以创建一本由操作符菜谱组成的 “ 烹饪书 ” 。
📄️ 热发布者与冷发布者
到目前为止,我们一直认为所有 `Flux` (以及 `Mono` )都是相同的:它们都表示一个异步的数据序列,并且在您订阅之前不会发生任何事情。
📄️ 用 ConnectableFlux 向多个订阅者广播
有时,您可能不只是想把某些处理延迟到某一个订阅者的订阅时刻,而是希望让几个订阅者先集合到一起,然后再触发对数据源的订阅和数据生成。
📄️ 三种批处理方式
当您有大量元素、想把它们划分成批时, Reactor 中有三大类方案:分组( grouping )、窗口( windowing )和缓冲( buffering )。这三者在概念上很接近,因为它们都是把一个 `Flux<T>` 重新聚合成一个聚合体。分组和窗口会产生 `Flux<Flux<T>>` ,而缓冲则聚合为 `Collection<T>` 。
📄️ 用 ParallelFlux 并行处理任务
如今多核架构已是寻常之物,能够轻松地并行处理任务就显得尤为重要。 Reactor 为此提供了一种特殊类型 `ParallelFlux` ,它暴露了为并行处理优化过的操作符。
📄️ 替换默认调度器
正如我们在线程与调度器一节中所描述的, Reactor Core 自带多种 `Scheduler` 实现。虽然您随时可以通过 `new*` 工厂方法创建新实例,但每种 `Scheduler` 风格还有一个默认单例实例,可通过直接工厂方法获取(例如 `Schedulers.boundedElastic()` 与 `Schedulers.newBoundedElastic(…)` 的区别)。
📄️ 使用全局钩子
Reactor 还有另一类可配置的回调,它们会在各种情况下被 Reactor 操作符调用。这些回调都在 `Hooks` 类中设置,共分为三类:
📄️ 为响应式序列添加上下文
从命令式编程思维转向响应式编程思维时,遇到的一大技术挑战在于如何处理线程。
📄️ 上下文传播支持
自 3.5.0 起, Reactor-Core 内置了对 io.micrometer:context-propagation SPI 的支持。该库旨在作为一种便捷手段,在上下文这一概念的各种实现之间( ContextView/Context 即为一例)以及 ThreadLocal 变量之间进行适配。
📄️ 处理需要清理的对象
在非常特定的场景下,您的应用可能会遇到一些类型,它们在不再被使用之后需要某种形式的清理。这是一个高级场景 —— 例如当您使用引用计数对象,或处理堆外对象时。 Netty 的 `ByteBuf` 同时是这两种情况的典型例子。
📄️ 空安全
尽管 Java 目前还无法在类型系统中表达可空性标记,但 Project Reactor 的代码库使用 JSpecify 注解来标注其 API 、字段及相关类型用法的可空性。强烈建议阅读 JSpecify 用户指南,以熟悉这些注解及其语义。