Spring5中Reactor编程的Mono与Flux类源码解读

Spring5的函数式编程使用了ProjectReactor工程的类,使用最为多的就是Mono和Flux类型,其中Mono是针对0到1个元素进行操作,Flux是针对多个元素进行操作。要使用这两个类前提是自己要有jdk8,Lambda,函数式编程的基础,否则请先学习了以上知识再来接触Spring5的Mono和FLux。

我们针对Mono类的一行代码,来进行源码分析与讲解。代码如下:

Mono.just("hello").subscribe(System.out::println);

这行代码是生成有一个元素的Mono类,并打印“hello”字符串。

首先,通过Mono.just()方法生成了Mono类

	public static <T> Mono<T> just(T data) {
		return onAssembly(new MonoJust<>(data));
	}

以上代码可以看到是创建了一个MonoJust类型,这个类和Mono,FLux类型一样在reactor-core包中,其实Mono的每个方法都会对应生成一个Mono的子类,其子类很多,如下:

截图只是列举了一部分,Mono采用这种每个方法都生成一个类的方式是与jdk8中的Stream流水线的最大区别,目的是为了重用任意阶段的结果,且其所有子类都实现了Mono类的方法:

public abstract void subscribe(CoreSubscriber<? super T> actual);

这个方法我们后面会讲,它的作用就是处理后面的函数式的逻辑。

在返回MonoJust类型后,我们调用了subscribe(System.out::println)方法,这个方法在Mono类有具体实现,方法如下:

	public final Disposable subscribe(Consumer<? super T> consumer) {
		Objects.requireNonNull(consumer, "consumer");
		return subscribe(consumer, null, null);
	}

这个方法是所有Mono的子类执行subscribe(CoreSubscriber<? super T> actual)方法的入口,我们进入看下,执行到了如下方法:

	public final Disposable subscribe(
			@Nullable Consumer<? super T> consumer,
			@Nullable Consumer<? super Throwable> errorConsumer,
			@Nullable Runnable completeConsumer,
			@Nullable Consumer<? super Subscription> subscriptionConsumer) {
		return subscribeWith(new LambdaMonoSubscriber<>(consumer, errorConsumer,
				completeConsumer, subscriptionConsumer));
	}

我们看到有四个参数,根据字面意思即可理解,lambda表达式是第一个参数consumer,可以看到执行Lambda的方法时候创建了一个类型LambdaMonoSubscriber,这个类型封装了封装了四个参数。

后面进入此方法:

	@Override
	public final void subscribe(Subscriber<? super T> actual) {
		onLastAssembly(this).subscribe(Operators.toCoreSubscriber(actual));
	}

这个方法是重写了父类Publisher的suscribe方法,我们看到代码做了类型转换,通过类型转换就转换为了可以调用MonoJust中的subscribe方法了,MonoJust总的subscribe方法如下,所有的Mono子类都重写了此方法:

	@Override
	public void subscribe(CoreSubscriber<? super T> actual) {
		actual.onSubscribe(Operators.scalarSubscription(actual, value));
	}

然后通过LambdaMonoSubscriber的onSubscribe方法在调用Operators的request方法,再调用此LambdaMonoSubscriber的onNext方法,最后调用了我们自己写的Lambda表达式,如下:

	@Override
	public final void onNext(T x) {
		Subscription s = S.getAndSet(this, Operators.cancelledSubscription());
		if (s == Operators.cancelledSubscription()) {
			Operators.onNextDropped(x, Context.empty());
			return;
		}
		if (consumer != null) {
			try {
				consumer.accept(x);
			}

consumer就是我们传入进来的Lambda表达式,这个方法继承自Suscriber类

通过这种方式,Publisher发送的subscribe就被Subscriber类消费掉了。其实全程都是一个单线程的操作。借鉴了消费订阅模式。

关于Mono的方法很多,在此只是举了一个简单的例子,其他的方法也可以通过类似的方式去研究。

在此处有一篇比较好的介绍Reactor编程的文章

  • 7
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java Flux API和Java Reactor API都是用于响应式编程的工具,其FluxMono是两个核心Flux代表的是包含0到N个元素的异步序列。这个序列可以包含三种不同的信号:onNext、onComplete、onError。onNext信号表示序列的一个元素,onComplete信号表示序列结束,onError信号表示出现错误。 Mono代表的是包含0或1个元素的异步序列。它和Flux的区别在于,它要么只有一个元素,要么就是空序列。 WebFluxSpring 5引入的新的响应式Web框架,它基于Reactor库实现。WebFlux包含两个不同的编程模型:基于注解的模型和函数式编程模型。 下面是一个简单的示例,演示如何使用FluxMono: ```java // 创建一个包含1到10的整数序列 Flux<Integer> flux = Flux.range(1, 10); // 订阅这个序列并输出每个元素 flux.subscribe(System.out::println); // 创建一个包含单个字符串元素的Mono Mono<String> mono = Mono.just("Hello World"); // 订阅这个序列并输出元素 mono.subscribe(System.out::println); ``` WebFlux的应用示例: ```java @RestController public class UserController { @Autowired private UserService userService; @GetMapping("/users") public Flux<User> getAllUsers() { return userService.getAllUsers(); } @GetMapping("/users/{id}") public Mono<User> getUserById(@PathVariable("id") String id) { return userService.getUserById(id); } @PostMapping("/users") public Mono<User> createUser(@RequestBody User user) { return userService.createUser(user); } @PutMapping("/users/{id}") public Mono<User> updateUser( @PathVariable("id") String id, @RequestBody User user) { return userService.updateUser(id, user); } @DeleteMapping("/users/{id}") public Mono<Void> deleteUser(@PathVariable("id") String id) { return userService.deleteUser(id); } } ``` 在这个示例,我们创建了一个名为UserController的REST控制器,它包含了五个不同的请求处理方法。每个方法都返回一个FluxMono对象,以实现异步响应式编程。我们还注入了一个名为UserService的服务对象,它提供了所有用户相关的业务逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值