我正在开发一个 Spring webflux 项目,我想了解 抛出异常 与使用 Mono.error().
之间的区别如果有这样的验证类例如:
public class NameValidator {
public static boolean isValid(String name) {
if(StringUtils.isEmpty(name)) {throw new RuntimeException("Invalid name");}
return true;
}
}
public class NameValidator2 {
public static Mono<Object> isValid(String name) {
if(StringUtils.isEmpty(name)) {
return Mono.error(new RuntimeException("Invalid name"));}
return Mono.just(true);
}
}
每种方法的优点和缺点是什么。使用 spring webflux 处理反应式流时何时使用其中一种?
正如@Joao已经说过的,处理错误的推荐方法是在
error
(Publisher
/Mono.error
)上调用Flux.error
方法。
我想向您展示一个示例,其中传统的
throw
并不像您期望的那样工作:
public void testErrorHandling() {
Flux.just("a", "b", "c")
.flatMap(e -> performAction()
.onErrorResume(t -> {
System.out.println("Error occurred");
return Mono.empty();
}))
.subscribe();
}
Mono<Void> performAction() {
throw new RuntimeException();
}
onErrorResume
运算符永远不会被执行,因为在组装Mono
之前抛出异常。
一般来说,
throw
的工作方式与Mono.error()
类似(Reactor捕获异常并将其转换为Mono.error
)。上面的例子不起作用,因为在创建Mono
之前的组装期间抛出了异常。
基本上你最终会得到相同的结果,并且两个选项之间没有区别(也许是性能方面的,但我没有发现任何支持这个观点的东西,所以我想它可以忽略不计。 唯一的“区别”是 Mono.error 遵循 Reactive Streams 规范,并按原样抛出异常(请参阅 https://github.com/reactive-streams/reactive-streams-jvm/blob/v1 了解更多信息)。 0.3/README.md#2.13)。然而,它并没有被禁止,但是如果您喜欢遵循标准和规范(我猜您会这样做),您应该考虑使用 Mono.error。