一、什么是 spring webflux?
- 定位:spring framework 5+ 提供的 响应式 web 框架,与 spring mvc 并列;
- 核心目标:支持 非阻塞、异步、事件驱动 的高并发 web 应用;
- 底层依赖:
- 响应式流规范(reactive streams)
- project reactor(
mono/flux) - 非阻塞服务器(默认 netty,也支持 undertow、servlet 3.1+ 容器)
✅ webflux ≠ webmvc 替代品,而是 互补技术栈,适用于不同场景。
二、何时使用 webflux?
| 场景 | 推荐 |
|---|---|
| 高并发 i/o 密集型(api 网关、实时推送、iot) | ✅ 强烈推荐 |
| 全链路响应式技术栈(r2dbc + webclient + reactive mq) | ✅ |
| 低并发传统业务系统(后台管理、简单 crud) | ❌ 用 webmvc 更简单 |
| 强事务性/复杂 sql(需 hibernate/jpa) | ❌ 不适合 |
三、快速入门:创建 webflux 项目
1. 使用 spring initializr(https://start.spring.io/)
选择:
- project: maven / gradle
- language: java
- spring boot: 3.x(推荐)
- dependencies:
spring reactive webspring data r2dbc(如需数据库)h2 database或mariadb driver(根据需要)
2. 手动添加依赖(maven)
<dependencies>
<!-- webflux 核心 -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-webflux</artifactid>
</dependency>
<!-- 响应式数据库(以 mariadb 为例) -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-data-r2dbc</artifactid>
</dependency>
<dependency>
<groupid>org.mariadb</groupid>
<artifactid>r2dbc-mariadb</artifactid>
<version>1.1.5</version>
</dependency>
<dependency>
<groupid>org.mariadb</groupid>
<artifactid>mariadb-java-client</artifactid>
<scope>runtime</scope>
</dependency>
<!-- 测试 -->
<dependency>
<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-test</artifactid>
<scope>test</scope>
</dependency>
<dependency>
<groupid>io.projectreactor</groupid>
<artifactid>reactor-test</artifactid>
<scope>test</scope>
</dependency>
</dependencies>3. 启动类(无需特殊注解)
@springbootapplication
public class webfluxdemoapplication {
public static void main(string[] args) {
springapplication.run(webfluxdemoapplication.class, args);
}
}🔍 启动日志将显示:
netty started on port 8080
四、两种编程模型
a. 注解式(annotation-based)— 类似 spring mvc
@restcontroller
@requestmapping("/users")
public class usercontroller {
@autowired
private userrepository userrepository;
// 返回单个对象
@getmapping("/{id}")
public mono<user> getuser(@pathvariable string id) {
return userrepository.findbyid(id);
}
// 返回列表流
@getmapping
public flux<user> getallusers() {
return userrepository.findall();
}
// 创建用户
@postmapping
public mono<user> createuser(@requestbody user user) {
return userrepository.save(user);
}
// sse:服务器推送事件
@getmapping(value = "/stream", produces = mediatype.text_event_stream_value)
public flux<string> streamevents() {
return flux.interval(duration.ofseconds(1))
.map(seq -> "event #" + seq);
}
}✅ 优点:学习成本低,与 mvc 风格一致
⚠️ 注意:方法必须返回 mono 或 flux
b. 函数式(functional)— 纯函数式路由
1. 定义 handler
@component
public class userhandler {
private final userrepository userrepository;
public userhandler(userrepository userrepository) {
this.userrepository = userrepository;
}
public mono<serverresponse> getuser(serverrequest request) {
string id = request.pathvariable("id");
mono<user> user = userrepository.findbyid(id);
return user
.flatmap(u -> serverresponse.ok().bodyvalue(u))
.switchifempty(serverresponse.notfound().build());
}
public mono<serverresponse> getallusers(serverrequest request) {
flux<user> users = userrepository.findall();
return serverresponse.ok().body(users, user.class);
}
}2. 定义 routerfunction(替代 @requestmapping)
@configuration
public class userrouter {
@bean
public routerfunction<serverresponse> userroutes(userhandler handler) {
return route()
.get("/users/{id}", handler::getuser)
.get("/users", handler::getallusers)
.build();
}
}✅ 优点:更符合响应式思想,易于单元测试,无反射开销
💡 适合构建轻量级、高内聚的 api
五、响应式数据访问(r2dbc)
1. 实体类
@table("users")
public class user {
@id
private long id;
private string name;
private string email;
// constructors, getters, setters
}
2. repository
public interface userrepository extends reactivecrudrepository<user, long> {
flux<user> findbyemail(string email);
}
3. application.yml 配置
spring:
r2dbc:
url: r2dbc:mariadb://localhost:3306/mydb
username: root
password: password支持连接池(需引入
io.r2dbc:r2dbc-pool)
六、响应式 http 客户端:webclient
替代 resttemplate,非阻塞调用外部服务:
@service
public class externalserviceclient {
private final webclient webclient;
public externalserviceclient() {
this.webclient = webclient.builder()
.baseurl("https://api.example.com")
.build();
}
public mono<userprofile> fetchprofile(string userid) {
return webclient.get()
.uri("/profiles/{id}", userid)
.retrieve()
.bodytomono(userprofile.class)
.onerrorresume(e -> mono.empty()); // 错误降级
}
}七、全局异常处理
@controlleradvice
public class globalexceptionhandler {
@exceptionhandler(usernotfoundexception.class)
public mono<responseentity<string>> handleusernotfound(exception ex) {
return mono.just(responseentity
.status(httpstatus.not_found)
.body("user not found"));
}
@exceptionhandler(exception.class)
public mono<responseentity<string>> handlegeneral(exception ex) {
return mono.just(responseentity
.status(httpstatus.internal_server_error)
.body("internal error"));
}
}也可使用函数式方式注册 webexceptionhandler。
八、测试:webtestclient
@springboottest(webenvironment = springboottest.webenvironment.random_port)
class usercontrollertest {
@autowired
private webtestclient webclient;
@test
void shouldgetuser() {
webclient.get().uri("/users/1")
.exchange()
.expectstatus().isok()
.expectbody(user.class)
.value(user -> assertthat(user.getname()).isequalto("alice"));
}
}九、性能与配置优化
1. 调整 netty 参数(application.yml)
server:
netty:
connection-timeout: 30s
max-in-memory-size: 10mb # 防止 oom2. 启用背压控制
flux.range(1, 1000)
.limitrate(100) // 控制上游发射速率
.onbackpressurebuffer(500); // 缓冲溢出数据3. 监控与指标
集成 micrometer + prometheus,监控 reactor.netty.connection.provider.active.connections 等指标。
十、常见陷阱与最佳实践
| 问题 | 建议 |
|---|---|
| 在 webflux 中调用 jdbc / thread.sleep() | ❌ 会阻塞 eventloop,导致服务不可用 |
| 混合使用 webmvc 和 webflux | ⚠️ 可以共存,但不要在同一个 controller 中混用 |
| 忽略背压 | ⚠️ 大流量下可能 oom,务必使用 limitrate / onbackpressurexxx |
过度使用 block() | ❌ 破坏响应式模型,仅用于测试或边界转换 |
✅ 总结:webflux 开发 checklist
- 使用
spring-boot-starter-webflux - 返回类型为
mono<t>或flux<t> - 数据库使用 r2dbc(非 jdbc)
- http 调用使用
webclient - 避免任何阻塞操作
- 使用
webtestclient测试 - 合理处理背压和错误
通过以上指南,你已掌握 spring boot + webflux 的完整开发能力。记住:webflux 的价值不在于“更快”,而在于“更高吞吐、更低资源消耗”。在合适的场景下使用它,将显著提升系统伸缩性。
官方文档:
- https://docs.spring.io/spring-framework/docs/current/reference/html/web-reactive.html
- https://r2dbc.io/
- https://projectreactor.io/docs
到此这篇关于spring boot + webflux 全面使用实践指南的文章就介绍到这了,更多相关spring boot webflux使用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论