Что такое Mono и Flux в Spring WebFlux?
- Чем Mono отличается от Flux?
- Почему в реактивном коде нельзя вызывать block()?
Mono — асинхронный результат из 0 или 1 элемента, Flux — поток из 0..N элементов (библиотека Project Reactor). Это описание вычисления: ничего не происходит, пока кто-то не подпишется (в WebFlux подписывается фреймворк, когда вы возвращаете Mono из контроллера). Преобразования — map, flatMap (для асинхронных шагов), filter, обработка ошибок — onErrorResume. block() внутри реактивного кода блокирует поток event loop и убивает смысл подхода.
- map — синхронное преобразование значения, flatMap — следующий асинхронный вызов
- Блокирующий драйвер (JDBC) в WebFlux — плохая идея: нужен R2DBC или вынос в отдельный пул
- Ошибки — сигнал в потоке, а не исключение в try/catch
А ещё Если всё приложение блокирующее, проще остаться на Spring MVC с виртуальными потоками
Подробно
@GetMapping("/users/{id}")
Mono<UserDto> user(@PathVariable long id) {
return repo.findById(id) // Mono<User>
.flatMap(u -> orders.countFor(u.id()) // асинхронно
.map(n -> new UserDto(u, n)))
.switchIfEmpty(Mono.error(new NotFound()));
}
@GetMapping(value = "/events", produces = "text/event-stream")
Flux<Event> events() { return bus.stream(); }Что хотят услышать
- Mono — 0..1, Flux — 0..N.
- Ленивость и подписка.
- map и flatMap.
- Запрет блокировок.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Mono — список элементов, Flux — ровно один элемент; оба вычисляются сразу при создании
- ✗Оба содержат 0..N элементов, но Flux вычисляется лениво, а Mono — сразу при создании
- ✓Mono — 0 или 1 элемент, Flux — 0..N; ничего не вычисляется до подписки
- ✗Значение из Mono в контроллере WebFlux принято получать вызовом block()
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.