5人参与 • 2025-07-25 • Java
spring webflux 是 spring framework 5+ 引入的非阻塞、响应式 web 框架,旨在充分利用现代多核处理器和异步 i/o 模型(如 netty、undertow、servlet 3.1+ 容器),处理海量并发连接,特别适合低延迟、高吞吐量的应用场景。它是 spring mvc 的补充,为响应式编程模型提供了完整的支持。
核心功能:
非阻塞 & 响应式核心:
flux
(0…n 个元素) 和 mono
(0…1 个元素) 作为核心响应式类型。函数式编程模型:
@controller
, @restcontroller
): 与 spring mvc 风格类似,但方法返回类型是 mono
/flux
/mono<void>
等响应式类型。routerfunction
和 handlerfunction
定义路由和处理逻辑,更显式地控制请求处理流程,减少注解开销。响应式 http 客户端 (webclient
):
resttemplate
。响应式 websocket 支持:
flux
/mono
。响应式 server-sent events (sse) 支持:
flux<serversentevent>
。与响应式数据存储集成:
背压 (backpressure) 支持:
主要使用场景:
何时 不 首选 webflux?
完整使用示例 (基于注解的 controller + reactive mongodb + webclient)
1. 依赖 (maven - pom.xml
):
<dependencies> <!-- spring boot starter webflux --> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-webflux</artifactid> </dependency> <!-- spring data reactive mongodb --> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-data-mongodb-reactive</artifactid> </dependency> <!-- project reactor (通常由 starter 带进来) --> <dependency> <groupid>io.projectreactor</groupid> <artifactid>reactor-core</artifactid> </dependency> </dependencies>
2. 实体类 (user.java
):
@data @noargsconstructor @allargsconstructor @document(collection = "users") // mongodb 集合映射 public class user { @id private string id; private string name; private string email; }
3. 响应式 repository (userrepository.java
):
public interface userrepository extends reactivemongorepository<user, string> { flux<user> findbyname(string name); // 响应式查询方法 }
4. service 层 (userservice.java
):
@service public class userservice { private final userrepository userrepository; private final webclient webclient; // 响应式 http 客户端 public userservice(userrepository userrepository, webclient.builder webclientbuilder) { this.userrepository = userrepository; this.webclient = webclientbuilder.baseurl("http://some-external-api.com").build(); } public flux<user> getallusers() { return userrepository.findall(); } public mono<user> getuserbyid(string id) { return userrepository.findbyid(id); } public mono<user> createuser(user user) { return userrepository.save(user); } public mono<user> updateuser(string id, user user) { return userrepository.findbyid(id) .flatmap(existinguser -> { existinguser.setname(user.getname()); existinguser.setemail(user.getemail()); return userrepository.save(existinguser); }); } public mono<void> deleteuser(string id) { return userrepository.deletebyid(id); } // 示例:使用 webclient 调用外部api并处理响应 public mono<string> fetchdatafromexternalapi() { return webclient.get() .uri("/data") .retrieve() .bodytomono(string.class) .onerrorresume(e -> mono.just("fallback data")); // 错误处理示例 } }
5. controller 层 (usercontroller.java
):
@restcontroller @requestmapping("/api/users") public class usercontroller { private final userservice userservice; public usercontroller(userservice userservice) { this.userservice = userservice; } // 获取所有用户 (返回 flux<user>) @getmapping public flux<user> getallusers() { return userservice.getallusers(); } // 根据id获取用户 (返回 mono<user>) @getmapping("/{id}") public mono<responseentity<user>> getuserbyid(@pathvariable string id) { return userservice.getuserbyid(id) .map(user -> responseentity.ok(user)) // 找到用户,返回200 ok .defaultifempty(responseentity.notfound().build()); // 用户不存在,返回404 } // 创建用户 (接受 mono<user> 请求体,返回 mono<user>) @postmapping @responsestatus(httpstatus.created) public mono<user> createuser(@requestbody mono<user> usermono) { return usermono.flatmap(userservice::createuser); } // 更新用户 @putmapping("/{id}") public mono<responseentity<user>> updateuser(@pathvariable string id, @requestbody mono<user> usermono) { return usermono.flatmap(user -> userservice.updateuser(id, user)) .map(updateduser -> responseentity.ok(updateduser)) .defaultifempty(responseentity.notfound().build()); } // 删除用户 (返回 mono<void> 表示操作完成) @deletemapping("/{id}") @responsestatus(httpstatus.no_content) public mono<void> deleteuser(@pathvariable string id) { return userservice.deleteuser(id); } // 示例:server-sent events (sse) 端点 - 模拟持续发送用户列表更新 @getmapping(value = "/stream", produces = mediatype.text_event_stream_value) public flux<user> streamuserupdates() { return flux.interval(duration.ofseconds(1)) // 每秒触发一次 .flatmap(tick -> userservice.getallusers().take(5)); // 每次发送前5个用户(模拟更新) } // 示例:调用外部api @getmapping("/external-data") public mono<string> getexternaldata() { return userservice.fetchdatafromexternalapi(); } }
6. 配置 (application.properties
or application.yml
):
# mongodb 连接配置 spring.data.mongodb.uri=mongodb://localhost:27017/mydatabase # (可选) 设置 netty 作为内嵌服务器 (默认通常是 netty) server.port=8080
示例说明:
user
实体和响应式的 spring data mongodb repository 接口。userrepository
进行响应式数据库操作 (findall
, findbyid
, save
, deletebyid
)。webclient
(通过 webclient.builder
构造) 用于进行非阻塞的 http 调用。fetchdatafromexternalapi
方法展示了基本用法和错误处理 (onerrorresume
)。flux
或 mono
。@restcontroller
和 @requestmapping
定义 rest 端点。@requestbody mono<user>
表示请求体是异步到达的。flux
或 mono
。getuserbyid
和 updateuser
展示了如何处理可能为空的结果,返回不同的 responseentity
状态码。deleteuser
返回 mono<void>
并设置 @responsestatus(httpstatus.no_content)
。streamuserupdates
方法:produces = mediatype.text_event_stream_value
表明这是一个 sse 端点。flux.interval
每秒生成一个信号。userservice.getallusers().take(5)
获取(模拟的)最新用户数据(这里简单取了前5个)并发送给客户端。客户端会持续接收到事件流。getexternaldata
方法展示了如何在 controller 中调用 service 层的 webclient 功能。curl
, postman 或浏览器(对于 /api/users/stream
)测试各个端点。关键注意事项:
thread.sleep()
、同步 io),会破坏响应式模型的优势,甚至可能导致性能下降或线程饥饿。flux
, mono
, 操作符如 map
, flatmap
, filter
, zip
, onerrorresume
等)需要学习和适应。hooks.onoperatordebug()
)和日志记录很重要。总结:
spring webflux 是一个强大的框架,为构建高性能、可扩展、资源高效的异步和非阻塞 web 应用程序和微服务提供了现代解决方案。它特别适合处理高并发、低延迟和流式数据场景。在决定采用 webflux 时,务必权衡其优势(性能、可伸缩性)与挑战(学习曲线、调试、库兼容性),确保它适合你的具体应用需求和团队技能。上面的完整示例展示了如何使用注解模型结合响应式 mongodb 和 webclient 构建一个基本的 crud api,并包含 sse 和外部 api 调用的示例。
到此这篇关于spring webflux 功能介绍,使用场景,完整使用示例的文章就介绍到这了,更多相关spring webflux 使用内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论