Spring WebFlux 是一个支持反应式编程的框架,旨在处理大量并发请求时提供更高的性能。WebFlux 是基于 Reactive StreamsReactor,并且可以与传统的 Servlet API(基于阻塞IO)和 非阻塞IO(如 Netty)共存。

下面是一个 Spring WebFlux 的快速入门教程,涵盖了项目设置、基本的 REST API 创建、响应式编程的概念。

1. 创建 Spring WebFlux 项目

通过 Spring Initializr 创建项目:

  • 访问 Spring Initializr
  • 选择以下依赖:
    • Spring WebFlux
    • Spring Boot DevTools(可选)
    • Lombok(可选,减少样板代码)
    • Spring Data Reactive MongoDB(可选,根据需求)

点击 Generate,下载并解压项目。

或者,通过命令行创建 Spring Boot 项目:

curl https://start.spring.io/starter.zip -d dependencies=webflux,devtools,lombok -d name=webflux-demo -d packageName=com.example.webfluxdemo -d javaVersion=11 -o webflux-demo.zip
unzip webflux-demo.zip
cd webflux-demo

2. 配置 WebFlux 主类

WebFlux 使用 @SpringBootApplication 注解启动应用,下面是一个基本的主类:

package com.example.webfluxdemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class WebfluxDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebfluxDemoApplication.class, args);
    }
}

3. 创建响应式 Controller

WebFlux 的核心是响应式编程,它基于 MonoFlux 两个主要概念:

  • Mono:表示一个异步返回的单一值或空值。
  • Flux:表示异步返回的多个值(一个流)。

创建一个简单的 REST API 控制器

package com.example.webfluxdemo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

@RestController
public class HelloController {

    @GetMapping("/hello")
    public Mono<String> sayHello() {
        return Mono.just("Hello, WebFlux!");
    }
}

  • 该控制器的 sayHello() 方法返回一个 Mono<String>,它表示一个异步返回的值。WebFlux 会在请求时异步处理 Mono 中的值,并返回给客户端。

4. 运行应用

使用以下命令启动应用:

./mvnw spring-boot:run

或者使用 IDE 直接运行 WebfluxDemoApplication 类。

访问 http://localhost:8080/hello,你应该能够看到响应:Hello, WebFlux!

5. 异步处理与延时

WebFlux 使得响应式处理变得非常简单,你可以轻松地模拟异步延时操作。例如,使用 Mono.delay() 方法模拟一个延时的操作。

package com.example.webfluxdemo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

import java.time.Duration;

@RestController
public class HelloController {

    @GetMapping("/hello-delay")
    public Mono&lt;String> sayHelloWithDelay() {
        return Mono.just("Hello, WebFlux!")
                   .delayElement(Duration.ofSeconds(3));  // 模拟延迟3秒
    }
}

访问 http://localhost:8080/hello-delay,你会发现响应延迟了3秒。

6. 使用 Flux 返回多个值

如果你需要返回多个异步数据,可以使用 Flux

package com.example.webfluxdemo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.time.Duration;

@RestController
public class HelloController {

    @GetMapping("/hello-stream")
    public Flux&lt;String> streamHello() {
        return Flux.just("Hello", "WebFlux", "Stream!")
                   .delayElements(Duration.ofSeconds(1));  // 每秒返回一个元素
    }
}

访问 http://localhost:8080/hello-stream,你会看到每秒返回一个 String,直到所有元素都返回。

7. 集成数据库(Reactive MongoDB 示例)

Spring WebFlux 可以与响应式数据库(如 MongoDB)集成。以下是如何配置和使用响应式 MongoDB 的简单示例。

依赖配置(pom.xml

&lt;dependency>
    &lt;groupId>org.springframework.boot&lt;/groupId>
    &lt;artifactId>spring-boot-starter-data-mongodb-reactive&lt;/artifactId>
&lt;/dependency>

配置 application.properties

spring.data.mongodb.uri=mongodb://localhost:27017/test

创建一个响应式 MongoDB 实体类

package com.example.webfluxdemo.model;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document
public class Person {

    @Id
    private String id;
    private String name;
    private int age;

    // Getters and Setters
}

创建响应式 MongoDB 仓库

package com.example.webfluxdemo.repository;

import com.example.webfluxdemo.model.Person;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;

public interface PersonRepository extends ReactiveMongoRepository&lt;Person, String> {
}

使用 PersonRepository 在 Controller 中查询数据

package com.example.webfluxdemo.controller;

import com.example.webfluxdemo.model.Person;
import com.example.webfluxdemo.repository.PersonRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

@RestController
public class PersonController {

    @Autowired
    private PersonRepository personRepository;

    @GetMapping("/person")
    public Mono&lt;Person> getPerson() {
        return personRepository.findById("1");  // 假设 ID 为 1 的 Person 存在
    }
}

8. 常见配置和优化

  • 线程池配置:WebFlux 可以与 Netty、Undertow 或 Tomcat 配合使用。如果你使用 Netty,可以通过 application.properties 配置服务器相关属性。
server.netty.max-initial-line-length=16384
server.netty.max-header-size=16384

  • 全局配置:可以使用 WebFluxConfigurer 类对 WebFlux 的全局配置进行定制,如 CORS、消息转换等。

9. 总结

  • WebFlux 是基于反应式编程的框架,能够处理大量并发请求。
  • 关键组件:Mono(单值)和 Flux(多个值)用于响应式处理。
  • 可以通过 NettyUndertowTomcat 等服务器进行非阻塞的 HTTP 请求处理。
  • 使用 Reactive MongoDBRedis 等响应式数据源,可以提高性能,尤其是在高并发场景下。

通过 WebFlux,你可以构建更高效、可伸缩的异步应用,尤其适合实时流处理和大规模并发系统。