Mono类型解析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mono类型解析相关的知识,希望对你有一定的参考价值。

参考技术A Consumer 是消费者接口,被@FunctionalInterface注解修饰,这意味着它可以看做是一个方法,Consumer接口中定义了一个accept方法。

实现Consumer接口的消费者需要重写accept方法,accept方法就是消费生产者生产出来的对象进行消费。Consumer对象可以这样定义:

Consumer对象可以定义某个对象的方法,或者是类的静态方法,这就是代表 在Consummer的accept方法中使用该对象去执行该方法,或者执行这个类的静态方法。也可以用lambda表达式来进行定义。

Function接口也是被@FunctionalInterface注解修饰修饰的,表示一个方法。Function接口中定义了一个apply方法:

与Consumer接口类似,Function接口的实现类需要实现apply方法,通常Function类型的对象作为参数都会去调用Function对象的apply方法,也就是执行这个Function。Function对象也可以按照Consumer接口一样的方式进行定义:

Function与Consumer的区别就在于,Consumer是没有返回值的,而Function是有返回值的,也因此,如果lambda表达式只有一行,Function中匿名方法中的内容是一个表达式(表示返回的值),而Consumer中匿名方法的内容是一条语句(执行的逻辑)。

Mono和Flux都实现了Publisher接口,也就是发布者,一个Mono对象中最多发射一个信号(可能是一个值,或者空,或者一个error),而Flux可以发射多个信号。
Publisher接口中只定义了一个subscribe方法:

subscribe方法就是绑定一个Subscriber去订阅这个Publisher中的信号。
Subscriber类的定义如下:

首先需要先创建一个Mono对象,Mono提供了一些方法创建Mono对象,如creat,just等:

创建出来的MonoJust,MonoCreate等对象都是Mono的子类,onAssembly方法是将创建好的Mono对象进行装饰增强。MonoJust,MonoCreate这些类都是重写了Mono中的抽象方法:

subcribe一个Consummer对象是执行父类Mono中定义的subcribe方法,并一直调用重载的方法,最后将参数构造为一个LambdaMonoSubscriber对象调用subscribeWith方法:

接着调用Mono类中实现Publisher接口中定义的subscribe方法:

然后调用实现CorePublisher接口中定义的subscribe方法,也是上面提到的需要子类去实现的Mono类中的抽象方法,以MonoJust为例,其实现如下:

调用actual的onSubcribe方法,actual就是刚才创建的LambdaMonoSubscriber对象,参数是一个ScalarSubscription类型的对象,其onSubcribe方法如下:

如果有异常会调用Subscription对象的cancel方法和LambdaMonoSubscriber对象自身的onError方法,否则会调用Subscription对象的request方法,这里的Subscription对象的实际类型为ScalarSubscription类型,其request方法如下:

request方法中汇调用LambdaMonoSubscriber对象的onNext方法和onComplete方法

基于以上的源码,可以总结如下:

如何从Mono获取实体类型 ?

如何使用单声道对象正确操作getter / setter

Mono<Product> productMono = webClient.get()
            .uri(catalogUrl + "/{productId}", productId)
            .retrieve()
            .bodyToMono(Product.class)
            .onErrorResume(err -> Mono.empty())
            .switchIfEmpty(Mono.error(new NoSuchProductException()));

然后我想把我的“产品单声道”POJO转换成产品。谢谢你的回答。

答案

访问Product实例的正确方法是使用map()操作,如下所示:

@GetMapping("/products/{productId}")
  public Mono<MappedProduct> getProduct(@PathVariable("productId") String productId) {
    return webClient.get()
      .uri(catalogUrl + "/{productId}", productId)
      .retrieve()
      .bodyToMono(Product.class)
      .onErrorResume(err -> Mono.empty())
      .switchIfEmpty(Mono.error(new NoSuchProductException()));
      .map(product -> productMapper(product));   // <-- here you can handle Product instance

  }

以上是关于Mono类型解析的主要内容,如果未能解决你的问题,请参考以下文章

Java ProjectReactor 响应式编程 Mono 简单工作流程解析

[语音识别] kaldi -- aidatatang_200zh脚本解析:音素训练

mono unity Xamarin 这三者之间是啥关系

[语音识别] kaldi -- aidatatang_200zh脚本解析:单音素解码

Unity使用Mono.Xml代替System.Xml 测试

自定义Mono,实现Unity Android平台代码更新