1. 概述

Spring 5 引入了 Spring WebFlux,为 Web 应用提供了响应式编程的支持。这意味着你可以构建非阻塞、事件驱动的服务,显著提升 I/O 密集型应用的吞吐能力。

本文将带你使用 @RestControllerWebClient 构建一个轻量级的响应式 REST 应用,并集成 Spring Security 实现接口级别的权限控制。

✅ 适合场景:高并发、长连接、数据流式传输(如实时通知、日志推送)
❌ 不适合场景:CPU 密集型任务(如复杂计算)


2. Spring WebFlux 框架核心

WebFlux 内部基于 Project Reactor,依赖其两个核心发布者类型:

  • Flux<T>:发布 0..N 个元素的数据流
  • Mono<T>:发布 0..1 个元素的单值流

它支持两种编程模型:

  1. 注解式(基于 @Controller / @RestController
  2. 函数式路由(Functional Endpoints)

本文聚焦于注解式开发,函数式风格我们已在其他文章中详细探讨过。

⚠️ 注意:WebFlux 并不依赖 Servlet 容器,虽然它也能运行在 Servlet 容器上(如 Tomcat),但推荐搭配 Netty 或 Undertow 以发挥完全的非阻塞优势。


3. 项目依赖

引入 spring-boot-starter-webflux 即可自动装配所有必要组件:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
    <version>3.1.2</version>
</dependency>

该 Starter 自动包含:

  • spring-bootspring-boot-starter:基础启动器
  • spring-webflux:响应式 Web 框架核心
  • reactor-core:响应式流实现
  • reactor-netty:默认的非阻塞 HTTP 客户端/服务器

📌 最新版本可从 Maven Central 获取。


4. 响应式 REST 应用设计

我们将构建一个简单的 EmployeeManagement 示例应用,涵盖以下功能:

  • 领域模型:Employee(含 id、name)
  • 使用 @RestController 提供响应式 REST 接口
  • 使用 WebClient 编写响应式客户端
  • 使用 Spring Security 保护敏感接口

5. 响应式 @RestController

WebFlux 的注解式控制器与 Spring MVC 高度相似,但返回值是响应式类型(Mono / Flux)。

先定义控制器骨架:

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

    private final EmployeeRepository employeeRepository;
    
    public EmployeeController(EmployeeRepository employeeRepository) {
        this.employeeRepository = employeeRepository;
    }
}

EmployeeRepository 需要是一个支持响应式流的仓库,比如基于 Spring Data R2DBC 或 MongoDB Reactive Driver 实现。

5.1 获取单个资源

返回单个员工信息,使用 Mono<Employee> 包装:

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

✅ 为什么用 Mono
因为根据 ID 查询最多返回一个结果,符合 0..1 的语义。

5.2 获取资源集合

获取所有员工列表,使用 Flux<Employee>

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

✅ 为什么用 Flux
集合数据是典型的 0..N 数据流,Flux 支持逐个发射元素,适合流式传输。


6. 响应式 Web Client

WebClient 是 Spring 5 推出的非阻塞 HTTP 客户端,取代了旧的 RestTemplate,完美支持响应式流。

创建一个简单的客户端:

public class EmployeeWebClient {

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

通过工厂方法 create() 初始化,指定基础 URL 后,后续请求可使用相对路径。

6.1 获取单个资源

调用 /employees/{id} 接口获取单个员工:

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

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

⚠️ 注意:.subscribe() 触发实际请求。在生产环境中应避免直接 subscribe,推荐通过 map/flatMap 继续链式操作或返回给上游。

6.2 获取资源集合

调用 /employees 获取员工列表:

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

bodyToFlux 会逐个解析响应流中的对象,适合处理大数据量集合。

📌 更多 WebClient 高级用法(如错误处理、过滤器、超时设置)可参考我们关于 WebClient 详解 的文章。


7. Spring WebFlux 安全控制

使用 Spring Security 可以轻松保护响应式接口。我们新增一个更新员工信息的接口,并限制仅 ADMIN 角色可访问。

7.1 添加受保护接口

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

这是一个典型的写操作,需要权限控制。

7.2 配置安全规则

创建安全配置类:

@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();
    }
}

关键点说明:

  • @EnableWebFluxSecurity:启用 WebFlux 环境下的安全支持
  • ServerHttpSecurity:响应式安全配置 DSL
  • authorizeExchange():用于路由级别的权限判断(类比 MVC 中的 authorizeRequests
  • httpBasic():启用 HTTP Basic 认证(测试方便,生产建议用 JWT)

📌 此配置确保只有拥有 ADMIN 角色的用户才能调用 /employees/update 接口。

📌 更详细的 WebFlux 安全配置可参考 Spring Security 5 响应式安全实践


8. 总结

本文通过一个简单的 Employee 示例,展示了如何使用 Spring WebFlux 构建响应式 REST 服务:

  • 使用 @RestController 返回 Mono / Flux 实现非阻塞接口
  • 使用 WebClient 编写响应式客户端,消费流式数据
  • 使用 @EnableWebFluxSecurityServerHttpSecurity 保护敏感接口

除此之外,WebFlux 还支持:

  • ✅ 响应式 WebSocket:实现双向流通信
  • WebSocketClient:响应式 WebSocket 客户端

📌 想了解如何使用响应式 WebSocket?查看我们深入讲解 Spring 5 响应式 WebSocket 的文章。

✅ 完整示例代码已托管至 GitHub:
https://github.com/example/spring-reactive-demo(原链接为示例 mock)


原始标题:Guide to Spring 5 WebFlux | Baeldung