Guide to Spring 5 WebFlux – Spring 5 WebFlux指南

最后修改: 2018年 7月 16日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Spring 5 includes Spring WebFlux, which provides reactive programming support for web applications. 

Spring 5包括Spring WebFlux,它为Web应用程序提供反应式编程支持。

In this tutorial, we’ll create a small reactive REST application using the reactive web components RestController and WebClient.

在本教程中,我们将使用反应式Web组件RestControllerWebClient创建一个小型反应式REST应用程序。

We’ll also look at how to secure our reactive endpoints using Spring Security.

我们还将研究如何使用Spring Security来保护我们的反应式端点。

2. Spring WebFlux Framework

2.Spring WebFlux框架

Spring WebFlux internally uses Project Reactor and its publisher implementations, Flux and Mono.

Spring WebFlux 在内部使用Project Reactor及其发布器实现FluxMono

The new framework supports two programming models:

新框架支持两种编程模式。

  • Annotation-based reactive components
  • Functional routing and handling

We’ll focus on the annotation-based reactive components, as we already explored the functional style – routing and handling in another tutorial.

我们将专注于基于注解的反应式组件,因为我们已经在另一个教程中探讨了功能式–路由和处理

3. Dependencies

3.依赖性

Let’s start with the spring-boot-starter-webflux dependency, which pulls in all other required dependencies:

让我们从spring-boot-starter-webflux依赖项开始,它拉入所有其他所需的依赖项。

  • spring-boot and spring-boot-starter for basic Spring Boot application setup
  • spring-webflux framework
  • reactor-core that we need for reactive streams and also reactor-netty
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
    <version>2.6.4</version>
</dependency>

The latest spring-boot-starter-webflux can be downloaded from Maven Central.

最新的spring-boot-starter-webflux可以从Maven中心下载。

4. Reactive REST Application

4.反应式REST应用

Now we’ll build a very simple reactive REST EmployeeManagement application using Spring WebFlux:

现在我们将使用Spring WebFlux构建一个非常简单的反应式RESTEmployeeManagement应用程序:

  • Use a simple domain model – Employee with an id and a name field
  • Build a REST API with a RestController to publish Employee resources as a single resource and as a collection
  • Build a client with WebClient to retrieve the same resource
  • Create a secured reactive endpoint using WebFlux and Spring Security

5. Reactive RestController

5.反应式RestController

Spring WebFlux supports annotation-based configurations in the same way as the Spring Web MVC framework.

Spring WebFlux支持基于注解的配置,其方式与Spring Web MVC框架相同。

To begin with, on the server, we create an annotated controller that publishes a reactive stream of the Employee resource.

首先,在服务器上,我们创建一个注释控制器,发布Employee资源的反应流。

Let’s create our annotated EmployeeController:

让我们创建我们的注释EmployeeController

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

    private final EmployeeRepository employeeRepository;
    
    // constructor...
}

EmployeeRepository can be any data repository that supports non-blocking reactive streams.

EmployeeRepository可以是任何支持非阻塞反应流的数据存储库。

5.1. Single Resource

5.1.单一资源

Then let’s create an endpoint in our controller that publishes a single Employee resource:

然后让我们在控制器中创建一个端点,发布一个单一的雇员资源

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

We wrap a single Employee resource in a Mono because we return at most one employee.

我们用一个Employee资源包住一个Mono,因为我们最多返回一个雇员。

5.2. Collection Resource

5.2.采集资源

We also add an endpoint that publishes the collection resource of all Employees:

我们还添加了一个端点,发布所有Employees的集合资源。

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

For the collection resource, we use a Flux of type Employee since that’s the publisher for 0..n elements.

对于集合资源,我们使用一个Flux类型的Employee,因为那是0..n元素的发布者。

6. Reactive Web Client

6.反应式网络客户端

WebClient, introduced in Spring 5, is a non-blocking client with support for reactive streams.

WebClient,在Spring 5中引入,是一个非阻塞式客户端,支持反应式流。

We can use WebClient to create a client to retrieve data from the endpoints provided by the EmployeeController.

我们可以使用WebClient来创建一个客户端,从EmployeeController提供的端点中获取数据。

Let’s create a simple EmployeeWebClient:

让我们创建一个简单的EmployeeWebClient

public class EmployeeWebClient {

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

    // ...
}

Here we have created a WebClient using its factory method create. It’ll point to localhost:8080, so we can use relative URLs for calls made by this client instance.

这里我们使用其工厂方法create创建了一个WebClient。它将指向localhost:8080,所以我们可以使用相对的URL来调用这个客户端实例。

6.1. Retrieving a Single Resource

6.1.检索单个资源

To retrieve a single resource of type Mono from endpoint /employee/{id}:

要从端点/employee/{id}中检索类型为Mono的单个资源。

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

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

6.2. Retrieving a Collection Resource

6.2.检索一个集合资源

Similarly, to retrieve a collection resource of type Flux from endpoint /employees:

类似地,要从端点/employees检索Flux类型的集合资源。

Flux<Employee> employeeFlux = client.get()
  .uri("/employees")
  .retrieve()
  .bodyToFlux(Employee.class);
        
employeeFlux.subscribe(System.out::println);

We also have a detailed article on setting up and working with WebClient.

我们也有一篇关于设置和使用WebClient的详细文章.

7. Spring WebFlux Security

7.Spring WebFlux安全

We can use Spring Security to secure our reactive endpoints.

我们可以使用Spring Security来保护我们的反应式端点。

Let’s suppose we have a new endpoint in our EmployeeController. This endpoint updates Employee details and sends back the updated Employee.

我们假设在我们的EmployeeController中有一个新的端点。这个端点更新Employeedetails,并将更新后的Employee.送回。

Since this allows users to change existing employees, we want to restrict this endpoint to ADMIN role users only.

由于这允许用户改变现有的雇员,我们想把这个端点限制在ADMIN角色的用户。

As a result, let’s add a new method to our EmployeeController:

因此,让我们给我们的EmployeeController添加一个新方法。

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

Now, to restrict access to this method, let’s create SecurityConfig and define some path-based rules to allow only ADMIN users:

现在,为了限制对这个方法的访问,让我们创建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();
    }
}

This configuration will restrict access to the endpoint /employees/update. Therefore, only users with a role ADMIN will be able to access this endpoint and update an existing Employee.

此配置将限制对端点/employees/update的访问。因此,只有具有ADMIN角色的用户才能访问这个端点并更新现有的Employee.

Finally, the annotation @EnableWebFluxSecurity adds Spring Security WebFlux support with some default configurations.

最后,注解@EnableWebFluxSecurity添加了Spring Security WebFlux支持和一些默认配置。

For more information, we also have a detailed article on configuring and working with Spring WebFlux security.

欲了解更多信息,我们还有一篇关于配置和使用Spring WebFlux安全的详细文章。

8. Conclusion

8.结语

In this article, we explored how to create and work with reactive web components as supported by the Spring WebFlux framework. As an example, we built a small Reactive REST application.

在这篇文章中,我们探讨了如何创建和使用Spring WebFlux框架所支持的反应式Web组件。作为一个例子,我们建立了一个小型的反应式REST应用。

Then we learned how to use RestController and WebClient to publish and consume reactive streams.

然后我们学习了如何使用RestControllerWebClient来发布和消费反应式流。

We also looked into how to create a secured reactive endpoint with the help of Spring Security.

我们还研究了如何在Spring Security的帮助下创建一个安全的反应式端点。

Other than Reactive RestController and WebClient, the WebFlux framework also supports reactive WebSocket and the corresponding WebSocketClient for socket style streaming of Reactive Streams.

除了反应式RestControllerWebClientWebFlux框架还支持反应式WebSocket和相应的WebSocketClient,用于反应式流的套接字风格。

For more information, we also have a detailed article focused on working with Reactive WebSocket with Spring 5.

欲了解更多信息,我们还有一篇专注于使用Spring 5的Reactive WebSocket工作的详细文章

Finally, the complete source code used in this article is available over on Github.

最后,本文中使用的完整源代码可在Github上获取。