Java 在哪里使用Mono/Flux?

Java 在哪里使用Mono/Flux?,java,reactive-programming,spring-webflux,project-reactor,Java,Reactive Programming,Spring Webflux,Project Reactor,我被迫改用WebFlux进行反应式编程(在短时间内),我很难理解它。也许是因为缺少示例,或者是因为我从未做过函数式编程 无论如何,我的问题是在哪里使用Mono/Flux,在哪里可以使用普通对象?例如,我的控制器正在等待一个@Valid User对象,它应该是@Valid Mono还是类似Mono的东西?如果说它只是一个用户对象,我会将它传递到我的服务层,我想在将密码保存到反应式MongoDb之前对其进行编码,我是否应该写: User.setPassword(...); return reacti

我被迫改用WebFlux进行反应式编程(在短时间内),我很难理解它。也许是因为缺少示例,或者是因为我从未做过函数式编程

无论如何,我的问题是在哪里使用Mono/Flux,在哪里可以使用普通对象?例如,我的控制器正在等待一个@Valid User对象,它应该是@Valid Mono还是类似Mono的东西?如果说它只是一个用户对象,我会将它传递到我的服务层,我想在将密码保存到反应式MongoDb之前对其进行编码,我是否应该写:

User.setPassword(...);
return reactiveMongoDbRepository.save(user); //returns Mono<User> which is returned by the Controller to the View
换句话说,我是否被迫在任何地方使用这个管道来保持反应性,或者以命令式的方式执行某些步骤,比如打开对象,处理对象,然后将其包装回来


我知道我的问题似乎很傻,但我一点也不了解大局,阅读关于它的书籍并没有真正的帮助,请对我温柔一些。:)

当您需要顺序、异步和延迟执行时,请使用管道。在所有其他情况下(当您使用非阻塞代码时),您可以自由选择任何方法,通常最好使用最简单的方法

顺序非阻塞代码可以组织在函数中,您可以使用map/filter/doOnNext/…与反应式管道集成。。。组成部分

例如,考虑下面的<代码>订单< /代码>价格计算代码。

class PriceCalculator {

  private final Map<ProductCode, Price> prices;

  PriceCalculator(Map<ProductCode, Price> prices) {
    this.prices = prices;
  }

  PricedOrder calculatePrice(Order order) { // doesn't deal with Mono/Flux stuff
    Double price = order.orderLines.stream()
      .map(orderLine -> prices.get(orderLine.productCode))
      .map(Price::doubleValue)
      .sum();
    return new PricedOrder(order, price);
  }
}

class PricingController {

  public Mono<PricedOrder> getPricedOrder(ServerRequest request) {
    OrderId orderId = new OrderId(request.pathVariable("orderId"));
    Mono<Order> order = orderRepository.get(orderId);
    return order.map(priceCalculator::calculatePrice)
  }
}
类价格计算器{
私人最终地图价格;
价格计算器(地图价格){
价格=价格;
}
PricedOrder calculatePrice(订单){//不处理Mono/Flux内容
双倍价格=order.orderLines.stream()
.map(orderLine->prices.get(orderLine.productCode))
.map(Price::doubleValue)
.sum();
返回新的PricedOrder(订单、价格);
}
}
类价格控制器{
公共Mono getPricedOrder(服务器请求){
OrderId OrderId=neworderid(request.pathVariable(“OrderId”);
Mono order=orderRepository.get(orderId);
退货订单.map(价格计算器::计算价格)
}
}

第一种方法没有问题。当您需要顺序、异步和延迟执行时,请使用管道。在所有其他情况下(当您使用非阻塞代码时),您可以自由选择任何方法,通常最好使用最简单的方法。@IlyaZinkovich因此基本上我可以在任何地方使用用户对象,除了控制器和存储库层?简单地说,如果此用户处理代码是非阻塞的,则可以。将命令式代码封装在函数中,并将其一起提供给Mono/FluxThanks@IlyaZinkovich的某些映射/过滤/消费函数!
class PriceCalculator {

  private final Map<ProductCode, Price> prices;

  PriceCalculator(Map<ProductCode, Price> prices) {
    this.prices = prices;
  }

  PricedOrder calculatePrice(Order order) { // doesn't deal with Mono/Flux stuff
    Double price = order.orderLines.stream()
      .map(orderLine -> prices.get(orderLine.productCode))
      .map(Price::doubleValue)
      .sum();
    return new PricedOrder(order, price);
  }
}

class PricingController {

  public Mono<PricedOrder> getPricedOrder(ServerRequest request) {
    OrderId orderId = new OrderId(request.pathVariable("orderId"));
    Mono<Order> order = orderRepository.get(orderId);
    return order.map(priceCalculator::calculatePrice)
  }
}