Это третья часть серии блогов о реактивном программировании, в которой я познакомлю вас с WebFlux - реактивным веб-фреймворком Spring.   Исходный веб-фреймворк для Spring - Spring Web MVC - был построен для Servlet API и контейнеров Servlet. WebFlux был представлен как часть Spring Framework 5.0. В отличие от Spring MVC, он не требует Servlet API. Он полностью асинхронный и неблокирующий, реализует спецификацию Reactive Streams через проект Reactor (см. предыдущий пост в блоге ). WebFlux требует Reactor в качестве основной зависимости, но он также может взаимодействовать с другими реактивными библиотеками через Reactive Streams. Spring WebFlux поддерживает две разные модели программирования: на основе аннотаций и функциональную. 1.1.1 Аннотированные контроллеры Если вы работали со Spring MVC, модель на основе аннотаций будет выглядеть довольно знакомой, поскольку в ней используются те же аннотации из веб-модуля Spring, что и в Spring MVC. Основное отличие состоит в том, что теперь методы возвращают реактивные типы Mono и Flux. См. Следующий пример RestController с использованием модели на основе аннотаций: Некоторые пояснения к функциям, использованным в примере: map функция используется для преобразования элемента, испускаемого Mono, применяя функцию синхронной к нему. flatMap функция используется для преобразования элемент, испускаемый Mono асинхронно, возвращая значение, излучаемого другим Mono. defaultIfEmpty функция обеспечивает значение по умолчанию, если Mono завершается без каких - либо данных. 1.1.2 Функциональные конечные точки Модель функционального программирования основана на лямбда-выражении и оставляет за приложением полную обработку запроса. Он основан на концепциях HandlerFunctions и RouterFunctions. HandlerFunctions используются для генерации ответа на данный запрос: RouterFunction используется для маршрутизации запросов к HandlerFunctions:  Продолжая с тем же примером ученика, мы получим что-то вроде следующего, используя функциональный стиль.   A StudentRouter: И StudentHandler: Некоторые пояснения к функциям, использованным в примере: switchIfEmpty функция имеет ту же цель, defaultIfEmpty, но вместо того, чтобы обеспечить значение по умолчанию, она используется для обеспечения альтернативного Mono. Сравнивая две модели, мы видим, что: Для использования функционального варианта требуется еще немного кода для таких вещей, как получение входных параметров и синтаксический анализ до ожидаемого типа. Не полагаясь на аннотации, но написание явного кода предлагает некоторую большую гибкость и может быть лучшим выбором, если нам, например, нужно реализовать более сложную маршрутизацию. WebFlux работает в средах выполнения, отличных от сервлетов, таких как Netty и Undertow (неблокирующий режим), а также в средах выполнения сервлетов 3.1+, таких как Tomcat и Jetty. По умолчанию стартер Spring Boot WebFlux использует Netty, но его легко переключить, изменив зависимости Maven или Gradle. Например, чтобы переключиться на Tomcat, просто исключите spring-boot-starter-netty из зависимости spring-boot-starter-webflux и добавьте spring-boot-starter-tomcat: Spring Boot обеспечивает автоматическую настройку Spring WebFlux, которая хорошо работает в общих случаях. Если вам нужен полный контроль над конфигурацией WebFlux, можно использовать аннотацию @EnableWebFlux (эта аннотация также потребуется в простом приложении Spring для импорта конфигурации Spring WebFlux). Если вы хотите сохранить конфигурацию Spring Boot WebFlux и просто добавить дополнительную конфигурацию WebFlux, вы можете добавить свой собственный класс @Configuration типа WebFluxConfigurer (но без @EnableWebFlux). Подробные сведения и примеры см. в документации по конфигурации WebFlux. Чтобы получить поддержку Spring Security WebFlux, сначала добавьте в свой проект зависимость spring-boot-starter-security. Теперь вы можете включить его, добавив @EnableWebFluxSecurity аннотацию в свой класс Configuration (доступно с Spring Security 5.0). В следующем упрощенном примере будет добавлена ​​поддержка двух пользователей, один с ролью USER, а другой с ролью ADMIN, принудительно применить базовую аутентификацию HTTP и потребовать роль ADMIN для любого доступа к пути /student/admin: Также можно защитить метод, а не путь, сначала добавив аннотацию @EnableReactiveMethodSecurity к вашей конфигурации:  А затем добавляем @PreAuthorize аннотацию к защищаемым методам. Например, мы можем захотеть, чтобы наши методы POST, PUT и DELETE были доступны только для роли ADMIN. Затем к этим методам можно применить аннотацию PreAuthorize, например: Spring Security предлагает дополнительную поддержку, связанную с приложениями WebFlux, например защиту CSRF, интеграцию OAuth2 и реактивную аутентификацию X.509. Для получения дополнительной информации прочтите следующий раздел в документации Spring Security: Реактивные приложения Spring WebFlux также включает реактивный, полностью неблокирующий веб-клиент. У него есть функциональный, свободный API, основанный на Reactor. Давайте рассмотрим (еще раз) упрощенный пример того, как WebClient можно использовать для запроса нашего StudentController: Для тестирования вашего реактивного веб-приложения WebFlux предлагает WebTestClient, который поставляется с API, аналогичным WebClient. Давайте посмотрим, как мы можем протестировать наш StudentController с помощью WebTestClient: В Spring 5 WebSockets также получает дополнительные реактивные возможности. Чтобы создать сервер WebSocket, вы можете создать реализацию WebSocketHandler интерфейса, которая содержит следующий метод: Этот метод вызывается при установке нового соединения WebSocket и позволяет обрабатывать сеанс. Он принимает в WebSocketSession качестве входных данных и возвращает Mono <Void>, чтобы сигнализировать о завершении обработки сеанса приложением. WebSocketSession имеет методы, определенные для обработки входящих и исходящих потоков: Spring WebFlux также предоставляет WebSocketClient реализации для Reactor Netty, Tomcat, Jetty, Undertow и стандартной Java. Для получения дополнительной информации прочтите следующую главу в документации Spring's Web on Reactive Stack: WebSockets RSocket - это протокол, моделирующий семантику реактивных потоков по сети. Это двоичный протокол для использования в транспортных потоках байтовых потоков, таких как TCP, WebSockets и Aeron. В качестве введения в эту тему я рекомендую следующий пост в блоге, который написал мой коллега Pär: An introduction to RSocket А для получения дополнительной информации о поддержке Spring Framework протокола RSocket Это сообщение в блоге продемонстрировало, как WebFlux можно использовать для создания реактивного веб-приложения. В следующем и последнем посте этой серии будет показано, как мы можем сделать весь наш стек приложений полностью неблокирующим, также реализовав неблокирующую связь с базой данных - с помощью R2DBC (Reactive Relational Database Connectivity)! Spring Framework documentation - Web on Reactive Stack Spring Boot Features - The Spring WebFlux framework Spring Security - Reactive Applications