如何在Reactor WebFlux中对对象进行增强?

huangapple go评论97阅读模式
英文:

How to do enrichment of an object in reactor webflux?

问题

我有一个接口

public interface Enricher {
   Mono<MyObject> enrich(MyObject obj);
}
我有这个接口的实现,它返回更新后的 MyObject。

我有另一个名为 **CompositeEnricher** 的实现,它在构造函数中接受 Enricher 列表并执行数据增强。

在非响应式世界中,我会这样写

/*
请注意,以下代码仅适用于 Enricher 接口返回 MyObject 而不是 Mono 的情况
*/

public class CompositeEnricher implements Enricher {

private final List enrichers;

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

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

我该如何改成响应式,以便 Enricher 的每个实现都返回 Mono<MyObject>,包括实现 Enricher 接口的 CompositeEnricher?
英文:

I have an interface

    public interface Enricher {
       Mono&lt;MyObject&gt; enrich(MyObject obj);
    }

I have implementations of this interface which returns the updated MyObject.

I have another implementation called CompositeEnricher which takes in List of Enricher in constructor and performs enrichment.

In non-reactive world, I will write something like this

/*
  Please note that following code is applicable only if Enricher interface returns MyObject instead of Mono&lt;MyObject&gt;
*/

public class CompositeEnricher implements Enricher {

  private final List&lt;Enricher&gt; enrichers;

  public CompositeEnricher(List&lt;Enricher&gt; enrichers) {
    this.enrichers = enrichers;
  }

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

How do I change it to reactive so that each of the implementations of Enricher return Mono<MyObject> including CompositeEnricher which implements Enricher interface?

答案1

得分: 1

这里实际上完全不需要一个单独的 CompositeEnricher 类 - 给定一个 List<Enricher> enrichers,你可以使用标准的 Java 流来简化你的 enrichers:

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

如果需要的话,你当然可以将这个实现成一个类,但同样也可以将其实现为某个辅助方法。

英文:

There's actually no need for a separate CompositeEnricher class here at all - given a List&lt;Enricher&gt; enrichers, you can simply reduce your enrichers using standard Java streams:

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

You can flesh this out into a class if you need to of course, but you could equally just leave this implemented as a helper method somewhere.

答案2

得分: 1

我使用了Mono.expand方法来解决了这个问题。但是我不得不使用enrichers.iterator()。想知道是否可以将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();
}
英文:

I figured out the problem using Mono.expand method. But I had to use enrichers.iterator(). Wondering if I can somehow put enrichers also in reactive chain instead of using iterator.

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

huangapple
  • 本文由 发表于 2020年8月5日 01:09:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/63251847.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定