SpringCloud-Demo项目中的RxJava入门实践指南
2025-06-07 21:08:40作者:庞眉杨Will
前言
在分布式系统开发中,响应式编程已经成为处理异步数据流的重要范式。本文将基于SpringCloud-Demo项目中的RxJava示例,深入浅出地讲解RxJava的核心概念和基础用法。
环境准备
首先需要在项目中添加RxJava的依赖:
<dependencies>
<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava</artifactId>
<version>1.3.8</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
RxJava核心概念
RxJava的核心是观察者模式,包含三个基本概念:
- Observable:被观察者,负责产生事件
- Observer/Subscriber:观察者,负责消费事件
- Subscription:订阅关系
事件类型包括:
- onNext():正常事件
- onCompleted():事件队列完结
- onError():事件队列异常
基础示例
Hello World示例
@Test
public void helloWorld() {
// 创建被观察者
Observable<String> producer = Observable.create(subscriber -> {
subscriber.onNext("hello world!");
subscriber.onNext("apple!");
subscriber.onNext("orange!");
subscriber.onNext("exit");
subscriber.onCompleted();
});
// 创建观察者
Subscriber<String> consumer = new Subscriber<String>() {
@Override
public void onCompleted() {
System.out.println("发送完成!");
}
@Override
public void onError(Throwable e) {
System.out.println("接受消息错误:" + e);
}
@Override
public void onNext(String s) {
System.out.println("收到消息:" + s);
}
};
// 建立订阅关系
producer.subscribe(consumer);
}
这个示例展示了RxJava最基本的用法:创建一个生产者Observable和一个消费者Subscriber,然后通过subscribe()方法建立订阅关系。
常用操作符
from操作符
将集合或数组转换为Observable:
@Test
public void from() {
List<String> source = Arrays.asList("rxJava", "from", "exit");
Observable.from(source).subscribe(s -> System.out.println("From: - " + s));
}
defer操作符
延迟创建Observable,直到有订阅者订阅时才创建:
@Test
public void defer() {
List<String> source = Arrays.asList("rxJava", "defer", "exit");
Observable<String> observable = Observable.defer(() -> {
System.out.println("新建一个Observale生产者");
return Observable.from(source);
});
observable.subscribe(s -> System.out.println("Defer1: - " + s));
observable.subscribe(s -> System.out.println("Defer2: - " + s));
}
startWith操作符
在数据流开头插入数据:
@Test
public void startWith() {
List<String> sources = Arrays.asList("rxJava", "startWith", "exit");
Observable.from(sources)
.startWith("Hello", "World")
.subscribe(s -> System.out.println("Start with: - " + s));
}
filter操作符
过滤数据,类似于Java 8 Stream中的filter:
@Test
public void filter() {
List<Integer> numbers = Arrays.asList(10, 2, 6, 3, 7, 5, 9, 8, 1);
Observable.from(numbers)
.filter(integer -> integer > 4)
.subscribe(integer -> System.out.println("Filter : " + integer));
}
map操作符
转换数据:
@Test
public void map() {
List<Integer> numbers = Arrays.asList(10, 2, 6, 3, 7, 5, 9, 8, 1);
Observable.from(numbers)
.map(integer -> "[map:" + integer + ']')
.subscribe(o -> System.out.println("Map - > " + o.toString()));
}
flatMap操作符
一对多转换:
@Test
public void flatMap() {
List<Integer> numbers = Arrays.asList(10, 2, 6, 3, 7, 5, 9, 8, 1);
Observable.from(numbers)
.flatMap(integer -> {
List<Integer> integers = Arrays.asList(integer, integer * 5, integer * 10, integer * 20);
return Observable.from(integers);
})
.subscribe(obj -> System.out.println("FlatMap: " + obj.toString()));
}
reduce操作符
聚合操作,类似递归:
@Test
public void reduce() {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
Observable.from(numbers)
.reduce((integer, integer2) -> integer * integer2)
.subscribe(integer -> System.out.println("1-9相乘结果:" + integer));
}
scan操作符
与reduce类似,但会输出每次计算结果:
@Test
public void scan() {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
Observable.from(numbers)
.scan((integer, integer2) -> integer + integer2)
.subscribe(integer -> System.out.println("Scan : " + integer));
}
高级应用:滑动窗口
windowCount操作符
固定大小的滑动窗口:
@Test
public void windowCount() {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
// 取相邻的2个数计算,然后跳跃2个事件
Observable.from(numbers)
.window(2, 2)
.subscribe(integerObservable ->
integerObservable
.reduce((integer, integer2) -> integer + integer2)
.subscribe(integer -> System.out.println("Window ->" + integer))
);
}
windowTime操作符
基于时间的滑动窗口:
@Test
public void windowTime() throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(1);
Observable inputEventStream = Observable.create(subscriber ->
subscriber.onNext("我是生产者.........."));
// 每个1s中输出一次
inputEventStream.window(1000, TimeUnit.MILLISECONDS)
.subscribe(o -> {
Calendar calendar = Calendar.getInstance();
int i = calendar.get(Calendar.SECOND);
System.out.println(i + " -->执行");
});
countDownLatch.await();
}
综合滑动窗口示例
@Test
public void windowUltimateDemo() throws InterruptedException {
// reduce 计算两个数字
Func2<Integer, Integer, Integer> publicSum = (integer, integer2) -> integer + integer2;
// 第一次统计
Func1<Observable<Integer>, Observable<Integer>> reduceFunc = integerObservable ->
integerObservable.reduce(0, publicSum);
// 程序计数等待器
CountDownLatch countDownLatch = new CountDownLatch(1);
// BehaviorSubject将数据流中的最新值推送给接受者
BehaviorSubject<Integer> behaviorSubject = BehaviorSubject.create();
behaviorSubject
// 1s作为一个基本块
.window(1000, TimeUnit.MILLISECONDS)
// 将flatMap汇总平铺成一个事件
.flatMap(reduceFunc)
// 对这个对象2个发送,步长为1
.window(2, 1)
// 对窗口里面的进行求和
.flatMap(reduceFunc)
.subscribe(integer ->
System.out.println(Thread.currentThread().getName() + "-每秒统计输出结果:-> " + integer));
for (int i = 0; i < 10000; i++) {
behaviorSubject.onNext(i);
// 200ms产生一个数据
Thread.sleep(200);
}
countDownLatch.await();
}
总结
本文通过SpringCloud-Demo项目中的RxJava示例,详细介绍了RxJava的核心概念和常用操作符。从最基本的观察者模式,到各种数据转换操作符,再到高级的滑动窗口应用,RxJava为处理异步数据流提供了强大的工具集。
在实际开发中,特别是在微服务架构下,RxJava可以帮助我们更好地处理异步事件流,构建响应式系统。建议读者通过实际编码练习来加深理解,逐步掌握RxJava的强大功能。
登录后查看全文
热门项目推荐
ERNIE-4.5-VL-28B-A3B-ThinkingERNIE-4.5-VL-28B-A3B-Thinking 是 ERNIE-4.5-VL-28B-A3B 架构的重大升级,通过中期大规模视觉-语言推理数据训练,显著提升了模型的表征能力和模态对齐,实现了多模态推理能力的突破性飞跃Python00
Kimi-K2-ThinkingKimi K2 Thinking 是最新、性能最强的开源思维模型。从 Kimi K2 开始,我们将其打造为能够逐步推理并动态调用工具的思维智能体。通过显著提升多步推理深度,并在 200–300 次连续调用中保持稳定的工具使用能力,它在 Humanity's Last Exam (HLE)、BrowseComp 等基准测试中树立了新的技术标杆。同时,K2 Thinking 是原生 INT4 量化模型,具备 256k 上下文窗口,实现了推理延迟和 GPU 内存占用的无损降低。Python00
MiniMax-M2MiniMax-M2是MiniMaxAI开源的高效MoE模型,2300亿总参数中仅激活100亿,却在编码和智能体任务上表现卓越。它支持多文件编辑、终端操作和复杂工具链调用Python00
HunyuanVideo-1.5暂无简介00
MiniCPM-V-4_5MiniCPM-V 4.5 是 MiniCPM-V 系列中最新且功能最强的模型。该模型基于 Qwen3-8B 和 SigLIP2-400M 构建,总参数量为 80 亿。与之前的 MiniCPM-V 和 MiniCPM-o 模型相比,它在性能上有显著提升,并引入了新的实用功能Python00
Spark-Formalizer-X1-7BSpark-Formalizer 是由科大讯飞团队开发的专用大型语言模型,专注于数学自动形式化任务。该模型擅长将自然语言数学问题转化为精确的 Lean4 形式化语句,在形式化语句生成方面达到了业界领先水平。Python00
GOT-OCR-2.0-hf阶跃星辰StepFun推出的GOT-OCR-2.0-hf是一款强大的多语言OCR开源模型,支持从普通文档到复杂场景的文字识别。它能精准处理表格、图表、数学公式、几何图形甚至乐谱等特殊内容,输出结果可通过第三方工具渲染成多种格式。模型支持1024×1024高分辨率输入,具备多页批量处理、动态分块识别和交互式区域选择等创新功能,用户可通过坐标或颜色指定识别区域。基于Apache 2.0协议开源,提供Hugging Face演示和完整代码,适用于学术研究到工业应用的广泛场景,为OCR领域带来突破性解决方案。00
项目优选
收起
deepin linux kernel
C
24
7
Ascend Extension for PyTorch
Python
173
193
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
647
263
TorchAir 支持用户基于PyTorch框架和torch_npu插件在昇腾NPU上使用图模式进行推理。
Python
269
93
暂无简介
Dart
622
140
本仓将收集和展示高质量的仓颉示例代码,欢迎大家投稿,让全世界看到您的妙趣设计,也让更多人通过您的编码理解和喜爱仓颉语言。
Cangjie
377
3.32 K
React Native鸿蒙化仓库
JavaScript
242
315
🎉 (RuoYi)官方仓库 基于SpringBoot,Spring Security,JWT,Vue3 & Vite、Element Plus 的前后端分离权限管理系统
Vue
1.1 K
620
仓颉编译器源码及 cjdb 调试工具。
C++
126
856
Nop Platform 2.0是基于可逆计算理论实现的采用面向语言编程范式的新一代低代码开发平台,包含基于全新原理从零开始研发的GraphQL引擎、ORM引擎、工作流引擎、报表引擎、规则引擎、批处理引引擎等完整设计。nop-entropy是它的后端部分,采用java语言实现,可选择集成Spring框架或者Quarkus框架。中小企业可以免费商用
Java
9
1