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 控制消费速度
相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
小羊没烦恼!3 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
俊昭喜喜里3 天前
java中的继承和多态的区别
java
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
譕痕3 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码3 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖3 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商
此时不提桶,更待何时3 天前
01-06-A-JVM排查实战详解
java·jvm