Чтобы лучше понять, как работают Flux и Mono, вы можете представить их как трубы. Когда вы пишете код - вы не выполняете операции с вашими данными, а только описываете, что должно происходить с данными, когда конвейер будет завершен. Чтобы завершить конвейер - вам нужно подписаться на него (это конец конвейера).
Например, этот код:
Mono sampleMono = Mono.just(1)
.map(Integer::toString)
.doOnNext(System.out::println)
В этом коде вы только скажете, чтодолжно быть сделано, когда кто-то подписывается на sampleMono
. когда кто-то это делает - тогда 1
будет отправлено, сопоставлено со строкой и выведено на консоль. Но это произойдет только после подписки.
Это что-то вроде водопровода - вы можете получить холодную воду из скважины и установить водонагреватель. Но вы, как правило, получаете теплую воду, пока не воспользуетесь душем или раковиной (вам нужно подписаться на теплую воду :)).
Mono и Flux ленивы - поэтому они будут излучать только тогда, когда кто-то подпишется. Конечно - все строки кода были выполнены, но они отвечают за создание «конвейера», и, пока вы не подпишетесь, они останутся неиспользованными. Но, возможно, java с оптимизаторами подойдет, и эти строки будут вообще удалены из машинного кода.