Как спроектировать / создать реактивный метод с помощью Project Reactor - PullRequest
0 голосов
/ 01 июля 2019

Я недавно на реактивной основе, основанной на проекте-реакторе, такой как 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);
  }

Пример 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);
  }

Есть ли разница между двумя примерами или они оба приемлемы?

Вопрос 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;
  }

Пример 2:

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

  public Mono<String> aMethod(String name){
    return Mono.just("Hello: " + name);
  }

Второй вопрос странный, я знаю, но мне интересно, что все методы должны возвращать Mono или Flux, или я могу использовать как Question2 / Example1.

1 Ответ

1 голос
/ 01 июля 2019

Вопрос1: да, есть разница.В примере 1 вы создаете String key вне Mono.fromCallable.Здесь нет ничего страшного, но если бы это была дорогая операция, вы бы все замедлили.

Также эта логика reactiveRedisOperations().opsForHash() выполняется из Mono.fromCallable.То же самое - если это было дорого, вы все замедляете.

Вопрос2: та же точка, что и в вопросе 1. Mono.just принимает обычный объект, а не тот, который будет вызываться позже при необходимости (например, Callable или Supplier).Таким образом, при использовании Mono.just вы немедленно платите цену инициализации аргумента.

В ваших примерах разница практически отсутствует, но Mono и Flux обычно используются для асинхронной цепочки дорогостоящих операций,поэтому ничто не блокируется, как звонки из базы данных или звонки в другие внешние сервисы.Посмотрите на мой пример ниже, где 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
...