如何使用 Project Reactor 设计/创建反应式方法

Bur*_*acı 2 java spring-boot project-reactor

我刚接触基于项目反应器的反应式框架,如 spring-webflux,我有一些关于它的问题。

问题 1:

示例 1:

  public Mono<String> doSome(String str){
    String key = str.substring(0, 5).toLowerCase() + str.substring(6);
    return getValueFromRedis(key);
  }

  public Mono<String> getValueFromRedis(String key){
    return reactiveRedisOperations().opsForHash().get("TestCache", key);
  }
Run Code Online (Sandbox Code Playgroud)

示例 2:

  public Mono<String> doSome(String str){
    return Mono.fromCallable(() -> {
      String key = str.substring(0, 5).toLowerCase() + str.substring(6);
      return getValueFromRedis(key);
    }).flatMap(stringMono -> stringMono);
  }

  public Mono<String> getValueFromRedis(String key){
    return reactiveRedisOperations().opsForHash().get("TestCache", key);
  }
Run Code Online (Sandbox Code Playgroud)

两个示例之间是否存在差异,或者它们都可以接受。

问题2:

示例 1:

  @PostMapping(value = "/greet")
  public Mono<String> greet(String name) {
    return Mono.fromCallable(() -> aMethod(name));
    // or return Mono.just(aMethod(name));
  }

  public String aMethod(String name){
    return "Hello: " + name;
  }
Run Code Online (Sandbox Code Playgroud)

示例 2:

  @PostMapping(value = "/greet")
  public Mono<String> greet(String name) {
    return aMethod(name);
  }

  public Mono<String> aMethod(String name){
    return Mono.just("Hello: " + name);
  }
Run Code Online (Sandbox Code Playgroud)

我知道第二个问题很奇怪,但我想知道所有方法都应该返回 Mono 或 Flux 还是我可以像 Question2/Example1 一样使用。

Sha*_*dov 5

问题1:是的,有区别。在示例 1 中,您String keyMono.fromCallable. 这在这里没什么大不了的,但如果它是昂贵的操作,你会减慢一切。

此逻辑reactiveRedisOperations().opsForHash()也是从Mono.fromCallable. 同样的事情 - 如果这是昂贵的,你正在减慢一切。

问题 2:与问题 1 中的相同点。Mono.just接受一个常规对象,而不是稍后需要时调用的对象(如CallableSupplier)。因此,在使用时,Mono.just您将立即付出参数初始化的代价。

在你的例子有几乎没有任何区别,但MonoFlux通常用于连锁昂贵的操作,在异步方式,因此没有被阻塞,如数据库调用或者其他外部服务调用。看看我下面的例子,其中 sleep 是模拟外部呼叫。注意打印语句的顺序。

public String superLongMethod() {
  System.out.println("superLongMethod");
  Thread.sleep(10000);
  return "ok";
}

System.out.println("before");
Mono.just(superLongMethod());
System.out.println("after");

// printed output is - before - superLongMethod - after

-----------------------------------------------------------------

System.out.println("before");
Mono.fromCallable(() -> superLongMethod());
System.out.println("after");

// printed output is - before - after - superLongMethod

-----------------------------------------------------------------

System.out.println("before");
String key = superLongMethod();
System.out.println("after");
return getValueFromRedis(key);

// printed output is - before - superLongMethod - after

-----------------------------------------------------------------

System.out.println("before");
Mono<String> mono = Mono.fromCallable(() -> {
  String key = superLongMethod();
  return getValueFromRedis(key);
}).flatMap(stringMono -> stringMono);
System.out.println("after");
return mono;

// printed output is - before - after - superLongMethod
Run Code Online (Sandbox Code Playgroud)