当前位置: 首页 > news >正文

SpringBoot响应式编程 WebFlux入门教程

🍁 作者:知识浅谈,CSDN签约讲师,CSDN博客专家,华为云云享专家,阿里云专家博主
📌 擅长领域:全栈工程师、爬虫、ACM算法
🔥 微信:zsqtcyw 联系我领取学习资料

🤞SpringBoot响应式编程 WebFlux入门教程🤞

    • 🎈概述
    • 🎈快速入门
    • 🎈关键概念
    • 🎈配置细节
    • 🎈测试方法
    • 🍚总结

🎈概述

Spring Boot响应式编程的核心框架之一是WebFlux,它是专为反应式编程设计的Web框架。与传统的Spring MVC相比,WebFlux具有显著的不同:它是异步非阻塞的,这意味着它能够通过较少的线程处理高并发请求。WebFlux底层完全基于Netty、Reactor和Spring Web,利用异步处理、消息队列(内存)和事件回调机制,实现了一套高效的响应式系统。
优点

  • 高并发能力:通过异步非阻塞的IO模型,WebFlux能使用少量资源处理大量请求。
  • 高效资源利用:在传统的阻塞式编程中,如果请求需要IO操作(如数据库访问或调用第三方服务),线程将阻塞等待操作完成。而在- WebFlux中,线程可以在等待IO操作完成的同时处理其他请求,从而提高资源利用率。
  • 实时数据流处理:WebFlux支持反应式数据流,能够实时响应数据变化,适用于实时数据处理和推送场景。

🎈快速入门

  1. 添加WebFlux依赖
    首先,你需要在Spring Boot项目的pom.xml文件中添加WebFlux的依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
  1. 编写响应式控制器
    接下来,创建一个响应式控制器来处理HTTP请求。使用@RestController和@RequestMapping注解来定义控制器和路由。使用Flux和Mono来定义异步非阻塞的响应式数据流。
package cn.juwatech.controller;import cn.juwatech.entity.User;
import cn.juwatech.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;@RestController
@RequestMapping("/users")
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/")public Flux<User> getAllUsers() {return userService.getAllUsers();}@GetMapping("/{id}")public Mono<User> getUserById(@PathVariable("id") String id) {return userService.getUserById(id);}@PostMapping("/")public Mono<User> createUser(@RequestBody User user) {return userService.createUser(user);}@PutMapping("/{id}")public Mono<User> updateUser(@PathVariable("id") String id, @RequestBody User user) {return userService.updateUser(id, user);}@DeleteMapping("/{id}")public Mono<Void> deleteUser(@PathVariable("id") String id) {return userService.deleteUser(id);}
}
  1. 编写响应式服务
    在服务层,同样使用Flux和Mono来处理业务逻辑,以保持响应式编程的一致性。
package cn.juwatech.service;import cn.juwatech.entity.User;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.HashMap;
import java.util.Map;@Service
public class UserService {private final Map<String, User> userMap = new HashMap<>();public Flux<User> getAllUsers() {return Flux.fromIterable(userMap.values());}public Mono<User> getUserById(String id) {return Mono.justOrEmpty(userMap.get(id));}public Mono<User> createUser(User user) {userMap.put(user.getId(), user);return Mono.just(user);}public Mono<User> updateUser(String id, User user) {userMap.put(id, user);return Mono.just(user);}public Mono<Void> deleteUser(String id) {userMap.remove(id);return Mono.empty();}
}
  1. 运行和测试
    运行Spring Boot应用,并通过浏览器或Postman等工具发送HTTP请求进行测试当然,接下来我将继续深入介绍Spring Boot响应式编程WebFlux的入门教程,包括一些关键概念、配置细节和测试方法。

🎈关键概念

  1. Reactor
    Reactor是Project Reactor的一部分,它是一个用于在JVM上构建响应式应用程序的库。Reactor提供了两种主要的数据类型:Flux和Mono。
  • Flux:表示一个包含0到N个元素的异步序列,可以发出三种类型的信号:正常的值、错误信号或完成信号。
  • Mono:表示一个包含0或1个元素的异步序列,它同样是响应式类型的,但用于那些最多只需要一个值的场景。
  1. Netty
    Netty是一个高性能、异步事件驱动的NIO框架,它支持快速开发可维护的高性能协议服务器和客户端。WebFlux底层默认使用Netty作为其非阻塞服务器。

🎈配置细节

  1. 端口配置
    在application.properties或application.yml文件中,你可以配置应用的端口号。默认情况下,Spring Boot应用会监听8080端口,但你可以根据需要进行修改。
# application.properties
server.port=8081
  1. 响应式数据库
    虽然WebFlux可以与传统的关系型数据库(如MySQL)一起使用,但为了更好地发挥响应式编程的优势,建议使用响应式数据库,如R2DBC(Reactive Relational Database Connectivity)。

在pom.xml中添加R2DBC的依赖,并配置数据源:

<dependency><groupId>io.r2dbc</groupId><artifactId>r2dbc-h2</artifactId><scope>runtime</scope>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-r2dbc</artifactId>
</dependency>

然后,在application.properties或application.yml中配置数据库连接:

# application.properties
spring.r2dbc.url=r2dbc:h2:mem:///testdb
spring.r2dbc.username=sa
spring.r2dbc.password=password

🎈测试方法

  1. 单元测试
    使用JUnit和Reactor Test工具进行单元测试。你可以编写测试用例来验证你的响应式方法是否按预期工作。

    import org.junit.jupiter.api.Test;
    import reactor.test.StepVerifier;public class UserServiceTest {private final UserService userService = new UserService(); // 假设UserService是无状态的@Testpublic void testGetAllUsers() {// 假设userService.getAllUsers()返回一个包含一些用户的FluxFlux<User> usersFlux = userService.getAllUsers();StepVerifier.create(usersFlux).expectNextMatches(user -> user.getId().equals("1") && user.getName().equals("Alice")).expectNextMatches(user -> user.getId().equals("2") && user.getName().equals("Bob")).verifyComplete();}
    }
    
  2. 集成测试
    使用Spring Boot的测试框架进行集成测试,以验证整个应用程序的响应式行为。

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.test.web.reactive.server.WebTestClient;@WebFluxTest(UserController.class)
public class UserControllerTest {@Autowiredprivate WebTestClient webTestClient;@Testpublic void testGetAllUsers() {webTestClient.get().uri("/users/").exchange().expectStatus().isOk().expectBodyList(User.class).hasSize(2).contains(user -> user.getId().equals("1") && user.getName().equals("Alice")).contains(user -> user.getId().equals("2") && user.getName().equals("Bob"));}
}

🍚总结

Spring Boot的WebFlux为开发者提供了一个全新的响应式编程模型,用于构建高性能、高扩展性的Web应用程序。通过使用当然,我将继续介绍Spring Boot WebFlux的一些高级特性和最佳实践,帮助你更深入地理解并有效地使用它。

大功告成,撒花致谢🎆🎇🌟,关注我不迷路,带你起飞带你富。
作者:码海浮生

相关文章:

SpringBoot响应式编程 WebFlux入门教程

&#x1f341; 作者&#xff1a;知识浅谈&#xff0c;CSDN签约讲师&#xff0c;CSDN博客专家&#xff0c;华为云云享专家&#xff0c;阿里云专家博主 &#x1f4cc; 擅长领域&#xff1a;全栈工程师、爬虫、ACM算法 &#x1f525; 微信&#xff1a;zsqtcyw 联系我领取学习资料 …...

LeetCode 383. 赎金信

题目 给你两个字符串&#xff1a;ransomNote 和 magazine &#xff0c;判断 ransomNote 能不能由 magazine 里面的字符构成。 如果可以&#xff0c;返回 true &#xff1b;否则返回 false 。 magazine 中的每个字符只能在 ransomNote 中使用一次。 示例 1&#xff1a; 输入&…...

python绘制电路图

要在 Python 中实现电路图&#xff0c;你可以使用一些专门的库来创建和可视化电路图。一个常用的库是 schemdraw&#xff0c;它可以用来绘制电路图&#xff0c;并支持多种电气组件和符号。 下面是一个使用 schemdraw 库绘制简单电路图的示例&#xff1a; 安装 schemdraw 库&am…...

Vue3 Suspense 和 defineAsyncComponent 结合使用方法

Suspense&#xff1a;用于协调对组件树中嵌套的异步依赖的处理。 defineAsyncComponent&#xff1a;定义一个异步组件&#xff0c;它在运行时是懒加载的。参数可以是一个异步加载函数&#xff0c;或是对加载行为进行更具体定制的一个选项对象。 异步组件的好处&#xff1a;使…...

GitHub中Codespace怎么使用;LLM模拟初始化;MLP:全连接神经网络的并行执行

目录 PyUnit unittest是什么 unittest怎么使用 GitHub中Codespace怎么使用 测试常用功能 LLM模拟初始化 参数解释 类属性设置 总结 MLP:全连接神经网络的并行执行 假设 代码解释 注意事项 PyUnit unittest是什么 unittest是Python的内置单元测试框架,原名PyUn…...

【rh】rh项目部署

【fastadmin】 1、项目先clone到本地&#xff0c;其中web为h5前端使用(gitclone后&#xff0c;把web内容放进去再提交)&#xff0c;其余为项目后端使用 2、安装本地环境&#xff0c;项目跑起来&#xff0c;步骤如下&#xff1a; 1&#xff09;查春.git 和 composer,json 版本信…...

VoxelNet: End-to-End Learning for Point Cloud Based 3D Object Detection

VoxelNet: End-to-End Learning for Point Cloud Based 3D Object Detection Abstract 摘要部分&#xff0c;作者首先指出了3D点云中目标检测的重要性&#xff0c;在自动驾驶导航、家政机器人以及增强现实和虚拟现实等多个领域有重要的作用。然后&#xff0c;提到了现有方法的…...

结构开发笔记(三):solidworks软件(二):小试牛刀,绘制一个立方体

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/141122350 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…...

LLM 量化算法AutoRound 0.3 发布及原理浅析

这里写自定义目录标题 AutoRound V0.3 特性原理浅析其他工作AutoRound 原理 AutoRound&#xff08;https://github.com/intel/auto-round&#xff09;在Llama3.1-8B-Instruct上效果明显优于AWQ/GPTQ等方法&#xff0c;在10个任务的平均准确率上我们以63.93%由于AWQ的63.15%和GP…...

汽车免拆诊断案例 | 2013款北京现代悦动车发动机偶尔无法起动

故障现象 一辆2013款北京现代悦动车&#xff0c;搭载G4FC发动机&#xff0c;累计行驶里程约为13.9万km。车主反映&#xff0c;发动机偶尔无法起动着机&#xff0c;断开点火开关&#xff0c;等待一会儿又可以起动着机。 故障诊断 接车后反复试车&#xff0c;当发动机无法起动着…...

React、AntD,封装动态表单

在React中使用Ant Design(简称AntD)来封装动态表单是一个常见的需求,特别是在需要灵活配置表单字段的场景下。以下是一个基本的步骤和示例代码,展示如何使用React和AntD来封装一个动态表单。 步骤 1: 安装必要的库 首先,确保你的项目中已经安装了react和antd。如果还没有…...

【Linux基础】Linux中的开发工具(3)--make/makefile和git的使用

目录 前言一&#xff0c;Linux项目自动化构建工具-make/makefile1. 背景2. 依赖关系和依赖方法3. 项目清理4. 使用方法和原理5. .PHONY的作用6. makefile中符号的使用 二&#xff0c;进度条的实现1. 理解回车换行2. 理解行缓冲区3. 版本14. 版本2 三&#xff0c;Linux上git的使…...

过滤了字母、数字、_、$的webshell命令执行技巧

目录 对于php5以上首先要解决的问题有 解决技巧 1.code长度小于35位 2.没有字母、数字、_ 、$ 3.怎么把文件放进服务器 4.怎么执行文件里面的内容 1.执行Linux命令 2.执行文件里面的shell命令 5.构造完整的code参数 6.我们还可以通过修改文件里面shell命令&#xff0c;…...

python-A+B again

[题目描述] 小理有一个非常简单的问题给你&#xff0c;给你两个整数 A 和 B&#xff0c;你的任务是计算 AB。输入格式&#xff1a; 输入共 2∗T1 行。 输入的第一行包含一个整数 T 表示测试实例的个数&#xff0c;然后 2∗T 行&#xff0c;分别表示 A 和 B 两个正整数。注意整数…...

C语言—函数递归

一、递归概念 递归其实是⼀种解决问题的⽅法&#xff0c;在C语⾔中&#xff0c;递归就是函数⾃⼰调⽤⾃⼰。下面举一个例子&#xff1a; 上述就是⼀个简单的递归程序&#xff0c;只不过上⾯的递归只是为了演⽰递归的基本形式&#xff0c;不是为了解决问题&#xff0c;代码最终…...

结构开发笔记(四):solidworks软件(三):绘制36x36方块摄像头示意体

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/141187797 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…...

【机器学习】Caltech-101的基本概念和使用方法以及Caltech-101和ImageNet的联系和区别

引言 Caltech-101数据集是一个广泛用于对象识别任务的数据库&#xff0c;它包含了大约9,000张图像&#xff0c;这些图像来自101个不同的对象类别。每个类别包含的图像数量大约在40到800张之间&#xff0c;大多数类别大约有50张图像。图像的分辨率大致为300200像素 文章目录 引言…...

mysql Ubuntu安装与远程连接配置

一、安装&#xff08;Ubuntu22环境安装mysql8&#xff09; 这里使用Xshell链接Ubuntu和mysql windows进行操作&#xff0c;特别提醒&#xff1a;安装之前建议对Ubuntu快照处理备份&#xff0c;避免安装中出错导致Ubuntu崩溃。 查看是否安装的有可以用指令&#xff1a;ps -ef|…...

c语言中比较特殊的输入格式

目录 一.%[ ] 格式说明符 1.基本用法 (1)读取字母字符: (2)读取数字字符: (3)读取所有字符直到遇到空格: (4)读取直到换行符: 2.使用范围和组合: 3.^ 取反操作 4.注意事项 (1). 字符范围的正确表示 (2). 避免字符集中的特殊字符冲突 (3).避免空字符集 (4). 输入长…...

远程命令行控制SSH

第一次接触SSH是ROS小车作为服务端&#xff0c;通过ubuntu电脑客户端访问。因为机器人接键盘和屏幕操作起来不方便&#xff0c;所以使用SSH进行连接&#xff0c;方便对小车的操作。 1.服务端安装 打开终端查看ssh是否安装 sudo service ssh status 如果未安装 sudo apt upd…...

钢铁百科:A572Gr60和SA572Gr60材质分析、A572Gr60和SA572Gr60简介

A572Gr60和SA572Gr60是两种常用的结构钢板&#xff0c;它们在材质、执行标准、化学成分、力学性能、交货状态、应用范围和常用规格方面有所不同。 材质&#xff1a; A572Gr60&#xff1a;属于美国材料与试验协会&#xff08;ASTM&#xff09;标准下的A572系列高性能结构钢&…...

一次sql请求,返回分页数据和总条数

日常搬砖&#xff0c;总少不了需要获取分页数据和总行数。 一直以来的实践是编码两次sql请求&#xff0c;分别拉分页数据和totalCount。 最近我在思考&#xff1a; 常规实践为什么不是 在一次sql请求中中执行多次sql查询或多次更新&#xff0c;显而易见的优势&#xff1a; ① 能…...

2.5 pyautogui 实现微信自动回复

第四节&#xff1a;实战微信自动回复 课程目标 学习如何通过pyautogui完成微信自动回复 课程内容 编码实现 import pyautogui as pg import time from pyautogui import ImageNotFoundException import pyperclip from cnocr import CnOcr import random ocr CnOcr() msg…...

观存储历史,论数据未来

数据存储 这几天我反复观看了腾讯云社区的《中国数据库前世今生》纪录片&#xff0c;每次的感受都大相径庭。以下是我在这段时间里对纪录片的两个不同感想&#xff0c;希望感兴趣的小伙伴们也能去观看一番。 一个是关于国产数据库的发展趋势的探讨&#xff1a;https://blog.c…...

linux:对目录的操作

一、对目录操作 1,打开目标目录 2.读取目录&#xff0c;&#xff0c; 3.关闭目录 目录 当文件看&#xff0c;只不过操作函数和操作文件函数不一样。 *1.opendir DIR *opendir(const char *name); 功能:打开一个目录获得一个目录流指针 参数:name:目录名 返回值&#xf…...

详解Redis 高可用的方式 Redis Cluster

Redis 高可用方式 Redis 提供了多种高可用性方案&#xff0c;主要包括以下几种方式&#xff1a; 主从复制&#xff08;Replication&#xff09; 主从复制是最基本的高可用性方案&#xff0c;通过将数据从一个主节点复制到多个从节点来实现数据的冗余和读写分离。主节点负责所…...

$clog2(1)=0

项目场景&#xff1a; 写ip 时&#xff0c; 使用参数化的方式实现2w1r 时&#xff0c;出现计算读返回index 时&#xff0c;减下溢&#xff01; 问题描述 verilog中会使用parameter 参数化&#xff0c;例如使用dpth 和$clog2(dpth)addr 。 常见的写法没有什么问题。 module …...

开发学习日记1

用这个系列博客记录下学习开发的一些小收获 git的使用&#xff1a; 说来惭愧&#xff0c;学到了大二&#xff0c;git的使用还是一团糟&#xff0c;记录一下如何使用git进行团队合作开发 当要加入其他人的项目时首先你要创建自己的分支&#xff08;克隆一下其他分支&#xff…...

孙宇晨领航波场TRON:引领数字资产迈向崭新纪元

​ 在风起云涌的数字资产领域&#xff0c;孙宇晨这个名字始终与创新、突破和引领紧密相连。作为波场TRON的创始人&#xff0c;他不仅是一位远见卓识的领导者&#xff0c;更是推动数字资产迈向新纪元的坚实力量。 自波场TRON诞生以来&#xff0c;孙宇晨便以其敏锐的洞察力…...

python运维(twenty-four day)

一、python基础 1、环境python2、python3 [rootpython ~]# yum list installed | grep python #检查是否有python包 [rootpython ~]# yum list installed | grep epel #检查是否有epel包 [rootpython ~]# yum -y install epel-release [rootpython ~]# yum -y instal…...