Spring Boot 响应式 WebFlux 从入门到精通

响应式编程基础

响应式编程是一种基于数据流和变化传播的编程范式。Spring WebFlux 是 Spring 框架提供的响应式 Web 栈,基于 Reactor 库实现。核心概念包括 Publisher(发布者)、Subscriber(订阅者)和背压(Backpressure)机制。

Reactor 提供两种核心类型:Mono(0-1 个元素)和 Flux(0-N 个元素)。创建示例:

java 复制代码
Mono.just("Hello")
Flux.fromIterable(Arrays.asList(1, 2, 3))

项目初始化

使用 Spring Initializr 创建项目时需选择 Reactive Web 依赖。Maven 配置示例:

XML 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

基础启动类需启用响应式支持:

java 复制代码
@SpringBootApplication
public class WebfluxApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebfluxApplication.class, args);
    }
}

路由与处理器

WebFlux 提供函数式路由声明方式。典型路由配置:

java 复制代码
@Bean
public RouterFunction<ServerResponse> routes() {
    return RouterFunctions.route()
        .GET("/hello", request -> 
            ServerResponse.ok().body(Mono.just("Hello WebFlux"), String.class))
        .build();
}

注解式控制器示例:

java 复制代码
@RestController
@RequestMapping("/users")
public class UserController {
    
    @GetMapping("/{id}")
    public Mono<User> getUser(@PathVariable String id) {
        return userRepository.findById(id);
    }
}

响应式数据库集成

Spring Data 提供响应式 Repository 支持。配置 MongoDB 示例:

yaml 复制代码
spring:
  data:
    mongodb:
      uri: mongodb://localhost:27017/test

响应式 Repository 接口:

java 复制代码
public interface UserRepository extends ReactiveMongoRepository<User, String> {
    Flux<User> findByAgeGreaterThan(int age);
}

错误处理机制

全局异常处理示例:

java 复制代码
@ExceptionHandler
public Mono<ResponseEntity<String>> handle(Exception ex) {
    return Mono.just(ResponseEntity
        .status(HttpStatus.INTERNAL_SERVER_ERROR)
        .body(ex.getMessage()));
}

响应式错误处理操作符:

java 复制代码
return userService.getUser(id)
    .onErrorResume(e -> Mono.just(new User("fallback")));

测试策略

WebTestClient 是测试 WebFlux 的主要工具:

java 复制代码
@SpringBootTest
class UserControllerTest {
    
    @Autowired
    private WebTestClient webClient;

    @Test
    void testGetUser() {
        webClient.get().uri("/users/1")
            .exchange()
            .expectStatus().isOk();
    }
}

高级特性

服务器推送事件(SSE)实现:

java 复制代码
@GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> streamEvents() {
    return Flux.interval(Duration.ofSeconds(1))
        .map(i -> "Event " + i);
}

响应式 WebSocket 支持:

java 复制代码
@Bean
public HandlerMapping webSocketHandlerMapping() {
    Map<String, WebSocketHandler> map = new HashMap<>();
    map.put("/echo", new EchoHandler());
    
    return new SimpleUrlHandlerMapping(map, -1);
}

性能优化

关键配置参数:

yaml 复制代码
server:
  reactor:
    netty:
      max-in-memory-size: 10MB
      connection-timeout: 30s

背压策略建议:

  • 使用 onBackpressureBuffer 缓冲溢出
  • 采用 limitRate 限制请求速率
  • 实现自定义 BaseSubscriber 控制消费速度
相关推荐
曹轲恒2 小时前
SpringBoot配置文件
java·spring boot
Apifox2 小时前
Apifox CLI + Claude Skills:将接口自动化测试融入研发工作流
前端·后端·测试
亓才孓2 小时前
[认识异常和错误]java
java·开发语言
码农水水2 小时前
中国电网Java面试被问:流批一体架构的实现和状态管理
java·c语言·开发语言·面试·职场和发展·架构·kafka
调试人生的显微镜2 小时前
使用Fiddler抓包工具获取微信公众号数据的完整教程
后端
货拉拉技术2 小时前
性能突破:星图平台架构优化
后端
UIUV2 小时前
Git 提交规范与全栈AI驱动开发实战:从基础到高级应用
前端·javascript·后端
程序员清风2 小时前
猿辅导二面:线上出现的OOM是如何排查的?
java·后端·面试