В чем суть Spring WebFlux и его ключевые отличия от Spring MVC?

«В чем суть Spring WebFlux и его ключевые отличия от Spring MVC?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Spring WebFlux — это полностью неблокирующий, реактивный веб-стек, построенный на Project Reactor. Он предназначен для приложений, требующих высокой конкуренции и эффективного использования ресурсов при небольшом числе потоков.

Ключевые концепции и отличия от Spring MVC:

Аспект Spring MVC (Императивный) Spring WebFlux (Реактивный)
Парадигма Блокирующая, на основе Servlet API Неблокирующая, на основе Reactive Streams
Модель потоков Один запрос — один поток (Thread-per-request) Небольшой фиксированный пул потоков (Event Loop)
Тип возвращаемого значения Object, ResponseEntity<T>, DeferredResult Mono<T>, Flux<T>
Базы данных Блокирующие драйверы (JDBC, JPA) Реактивные драйверы (R2DBC, MongoDB Reactive)
Backpressure Не поддерживается Поддерживается на уровне протокола (например, HTTP/2)

Пример реактивного контроллера:

@RestController
@RequestMapping("/users")
public class ReactiveUserController {
    private final ReactiveUserRepository repository;

    // Mono для 0 или 1 элемента
    @GetMapping("/{id}")
    public Mono<User> getUser(@PathVariable String id) {
        return repository.findById(id);
    }

    // Flux для потока элементов (N)
    @GetMapping
    public Flux<User> getAllUsers() {
        return repository.findAll();
    }

    // Реактивная обработка цепочки
    @PostMapping
    public Mono<ResponseEntity<User>> createUser(@RequestBody Mono<User> userMono) {
        return userMono
                .flatMap(repository::save)
                .map(savedUser -> ResponseEntity
                        .created(URI.create("/users/" + savedUser.getId()))
                        .body(savedUser));
    }
}

Когда использовать WebFlux:

  • Приложения с высокой конкуренцией и задержкой (например, чаты, стриминг).
  • Использование реактивных клиентов или баз данных.
  • Функциональные эндпоинты через RouterFunction и HandlerFunction.

Важно: WebFlux не делает код быстрее автоматически. Его преимущество — в масштабируемости при большом количестве одновременных соединений с медленными клиентами.