Перейти к основному содержимому

Руководство по Spring 5 WebFlux

· 5 мин. чтения

1. Обзор

Spring 5 включает Spring WebFlux, который обеспечивает поддержку реактивного программирования для веб-приложений.

В этом руководстве мы создадим небольшое реактивное приложение REST, используя реактивные веб-компоненты RestController и WebClient.

Мы также рассмотрим, как защитить наши реактивные конечные точки с помощью Spring Security.

2. Весенний фреймворк WebFlux

Spring WebFlux внутренне использует Project Reactor и его реализации издателя, Flux и Mono .

Новый фреймворк поддерживает две модели программирования:

  • Реактивные компоненты на основе аннотаций
  • Функциональная маршрутизация и обработка

Мы сосредоточимся на реактивных компонентах на основе аннотаций, так как мы уже изучили функциональный стиль — маршрутизацию и обработку в другом руководстве.

3. Зависимости

Начнем с зависимости spring-boot-starter-webflux , которая включает все остальные необходимые зависимости:

  • spring-boot и spring-boot-starter для базовой настройки приложения Spring Boot
  • `фреймворк spring-webflux`
  • реактор-ядро , который нам нужен для реактивных потоков, а также реактор-нетти
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<version>2.6.4</version>
</dependency>

Последнюю версию spring-boot-starter-webflux можно загрузить с Maven Central.

4. Реактивное приложение REST

Теперь мы создадим очень простое реактивное приложение REST EmployeeManagement , используя Spring WebFlux:

  • Используйте простую модель предметной области — сотрудник с идентификатором и полем имени .
  • Создайте REST API с RestController для публикации ресурсов сотрудников в виде отдельного ресурса и в виде коллекции.
  • Создайте клиент с WebClient для получения того же ресурса
  • Создайте защищенную реактивную конечную точку с помощью WebFlux и Spring Security .

5. Реактивный RestController

Spring WebFlux поддерживает конфигурации на основе аннотаций так же, как среда Spring Web MVC.

Для начала на сервере создаем аннотированный контроллер, который публикует реактивный поток ресурса Employee .

Давайте создадим наш аннотированный EmployeeController :

@RestController
@RequestMapping("/employees")
public class EmployeeController {

private final EmployeeRepository employeeRepository;

// constructor...
}

EmployeeRepository может быть любым репозиторием данных, который поддерживает неблокирующие реактивные потоки.

5.1. Единый ресурс

Затем давайте создадим конечную точку в нашем контроллере, которая публикует один ресурс Employee :

@GetMapping("/{id}")
private Mono<Employee> getEmployeeById(@PathVariable String id) {
return employeeRepository.findEmployeeById(id);
}

Мы оборачиваем один ресурс Employee в Mono , потому что возвращаем не более одного сотрудника.

5.2. Ресурс коллекции

Мы также добавляем конечную точку, которая публикует ресурс коллекции всех сотрудников :

@GetMapping
private Flux<Employee> getAllEmployees() {
return employeeRepository.findAllEmployees();
}

Для ресурса коллекции мы используем Flux типа Employee , так как это издатель для 0. . n элементов.

6. Реактивный веб-клиент

WebClient , представленный в Spring 5, представляет собой неблокирующий клиент с поддержкой реактивных потоков.

Мы можем использовать WebClient для создания клиента для получения данных из конечных точек, предоставленных EmployeeController.

Давайте создадим простой EmployeeWebClient :

public class EmployeeWebClient {

WebClient client = WebClient.create("http://localhost:8080");

// ...
}

Здесь мы создали WebClient , используя его фабричный метод create . Он будет указывать на localhost:8080, поэтому мы можем использовать относительные URL-адреса для вызовов, сделанных этим экземпляром клиента.

6.1. Получение одного ресурса

Чтобы получить один ресурс типа Mono из конечной точки /employee/{id} :

Mono<Employee> employeeMono = client.get()
.uri("/employees/{id}", "1")
.retrieve()
.bodyToMono(Employee.class);

employeeMono.subscribe(System.out::println);

6.2. Получение ресурса коллекции

Точно так же, чтобы получить ресурс коллекции типа Flux из конечной точки /employees :

Flux<Employee> employeeFlux = client.get()
.uri("/employees")
.retrieve()
.bodyToFlux(Employee.class);

employeeFlux.subscribe(System.out::println);

Также у нас есть подробная статья по настройке и работе с WebClient .

7. Весенняя безопасность WebFlux

Мы можем использовать Spring Security для защиты наших реактивных конечных точек.

Предположим, у нас есть новая конечная точка в нашем EmployeeController. Эта конечная точка обновляет сведения о сотруднике и отправляет обновленный сотрудник.

Поскольку это позволяет пользователям изменять существующих сотрудников, мы хотим ограничить эту конечную точку только пользователями роли ADMIN .

В итоге добавим в наш EmployeeController новый метод :

@PostMapping("/update")
private Mono<Employee> updateEmployee(@RequestBody Employee employee) {
return employeeRepository.updateEmployee(employee);
}

Теперь, чтобы ограничить доступ к этому методу, давайте создадим SecurityConfig и определим некоторые правила на основе пути, чтобы разрешить только пользователям ADMIN:

@EnableWebFluxSecurity
public class EmployeeWebSecurityConfig {

// ...

@Bean
public SecurityWebFilterChain springSecurityFilterChain(
ServerHttpSecurity http) {
http.csrf().disable()
.authorizeExchange()
.pathMatchers(HttpMethod.POST, "/employees/update").hasRole("ADMIN")
.pathMatchers("/**").permitAll()
.and()
.httpBasic();
return http.build();
}
}

Эта конфигурация ограничит доступ к конечной точке /employees/update . Поэтому только пользователи с ролью ADMIN смогут получить доступ к этой конечной точке и обновить существующего сотрудника.

Наконец, аннотация @EnableWebFluxSecurity добавляет поддержку Spring Security WebFlux с некоторыми конфигурациями по умолчанию.

Для получения дополнительной информации у нас также есть подробная статья о настройке и работе с безопасностью Spring WebFlux .

8. Заключение

В этой статье мы рассмотрели, как создавать и работать с реактивными веб-компонентами, поддерживаемыми инфраструктурой Spring WebFlux. В качестве примера мы создали небольшое приложение Reactive REST.

Затем мы узнали, как использовать RestController и WebClient для публикации и использования реактивных потоков.

Мы также рассмотрели, как создать защищенную реактивную конечную точку с помощью Spring Security.

Помимо Reactive RestController и WebClient , среда WebFlux также поддерживает реактивный WebSocket и соответствующий WebSocketClient для потоковой передачи реактивных потоков в стиле сокетов.

Для получения дополнительной информации у нас также есть подробная статья, посвященная работе с Reactive WebSocket с Spring 5 .

Наконец, полный исходный код, использованный в этой статье, доступен на Github .