使用Spring,我注意到只有在将doOnNext
对象分配给局部变量之前才对Flux对象执行doOnNext
。
为了观察这种行为,我使用了一个应用程序,它是使用使用默认设置创建的。我选择添加到POM中的唯一依赖项是“”。
@Controller
public class ProblemController {
@PostMapping("/upload")
public Mono<ResponseEntity<String>> upload(ServerWebExchange exchange) {
Flux<DataBuffer> body = exchange.getRequest().getBody()
// This prints!
.doOnNext(db -> System.out.println("Bytes A: " + db.readableByteCount()));
// Does not print anything...
body.doOnNext(db -> System.out.println("Bytes B: " + db.readableByteCount()));
return body
.next()
.map(db -> String.format("Uploaded %d bytes", db.readableByteCount()))
.map(s -> new ResponseEntity<String>(s, HttpStatus.ACCEPTED));
}
}
当我上传一个文件时
curl --location --request POST 'http://localhost:8080/upload' \
--form 'file=@"/path/to/file.txt"'
我可以看到只有Bytes A
消息被打印出来。
甚至我也添加了更多的doOnNext
回调,它们看起来都是执行的,
Flux<DataBuffer> body = exchange.getRequest().getBody()
// This prints!
.doOnNext(db -> System.out.println("Bytes A: " + db.readableByteCount()))
.doOnNext(db -> System.out.println("Bytes X: " + db.readableByteCount()));
打印Bytes A
和Bytes X
。
不过,它从不打印Bytes C
。这给我的印象是,当Flux对象被分配给局部变量(Flux<DataBuffer> body
)时,它会发生变化。
在这个例子中到底发生了什么?为什么我看不见Bytes C
打印?
发布于 2022-09-02 08:00:21
Flux或Mono中的每个操作符都返回一个新实例。当您链接调用时,最终将构建每个中间实例并获得“外部”实例。
对于Bytes C
示例,您只需调用该方法,而不将生成的新实例分配给任何变量,因此该实例已被垃圾收集,从未成为执行路径的一部分。
https://projectreactor.io/docs/core/release/reference/#faq.chain
https://stackoverflow.com/questions/73576552
复制相似问题