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 .