Как сделать обогащение объекта в реакторе webflux? - PullRequest
1 голос
/ 04 августа 2020

У меня есть интерфейс

    public interface Enricher {
       Mono<MyObject> enrich(MyObject obj);
    }

У меня есть реализации этого интерфейса, который возвращает обновленный MyObject.

У меня есть еще одна реализация под названием CompositeEnricher , которая принимает список of Enricher в конструкторе и выполняет обогащение.

В нереактивном мире я напишу что-то вроде этого

/*
  Please note that following code is applicable only if Enricher interface returns MyObject instead of Mono<MyObject>
*/

public class CompositeEnricher implements Enricher {

  private final List<Enricher> enrichers;

  public CompositeEnricher(List<Enricher> enrichers) {
    this.enrichers = enrichers;
  }

  @Override
  public MyObject enrich(MyObject myObject) {
    MyObject updated = myObject;
    for(Enricher enricher : enrichers) {
      updated = enricher.enrich(updated);
    }
    return updated;
  }
}

Как мне изменить его на реактивный, чтобы каждая из реализаций Enricher return Mono, включая CompositeEnricher, который реализует интерфейс Enricher?

Ответы [ 2 ]

1 голос
/ 05 августа 2020

На самом деле здесь вообще нет необходимости в отдельном классе CompositeEnricher - с учетом List<Enricher> enrichers вы можете просто уменьшить свои обогащения, используя стандартные Java потоки:

Enricher composite = enrichers.stream()
        .reduce((e1, e2) -> myObj -> e1.enrich(myObj).flatMap(myObj2 -> e2.enrich(myObj2)))
        .get();

Вы можете sh это в класс, если вам, конечно, нужно, но вы также можете просто оставить это реализованным как вспомогательный метод где-нибудь.

0 голосов
/ 06 августа 2020

Я решил проблему с помощью метода Mono.expand. Но мне пришлось использовать enrichers.iterator (). Интересно, могу ли я как-то добавить обогащающие элементы также в реактивную цепочку вместо использования итератора.

@Override
    public Mono<User> enrich(User user) {
        Iterator<Enricher> iterator = enrichers.iterator();
        Function<User, Publisher<User>> enrichmentFunction = u -> iterator.hasNext() ? iterator.next().enrich(u) : Mono.empty();
        return Mono.just(user)
                .expand(enrichmentFunction)
                .last();
    }
...