Spring Webflux 详解

2024-03-07 00:52
文章标签 java 详解 spring webflux

本文主要是介绍Spring Webflux 详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

目录

0、组件对比

1、WebFlux

1、引入    

2、Reactor Core

1、HttpHandler、HttpServer

3、DispatcherHandler

1、请求处理流程

4、注解开发

1、目标方法传参

2.返回值写法

5、文件上传

6、错误处理

7、RequestContext

8、自定义Flux配置

9、Filter

 WebFlux:底层完全基于netty+reactor+springweb 完成一个全异步非阻塞的web响应式框架 底层:异步 + 消息队列(内存) + 事件回调机制 = 整套系统 优点:能使用少量资源处理大量请求;

0、组件对比

Mono: 返回0|1 数据流

Flux:返回N数据流

1、WebFlux

底层基于Netty实现的Web容器与请求/响应处理机制

参照:Spring WebFlux :: Spring Framework

1、引入    

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.1.6</version></parent>
​
​
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency></dependencies>

Context 响应式上下文数据传递; 由下游传播给上游;

以前: 浏览器 --> Controller --> Service --> Dao: 阻塞式编程

现在: Dao(数据源查询对象【数据发布者】) --> Service --> Controller --> 浏览器: 响应式

大数据流程: 从一个数据源拿到大量数据进行分析计算;

ProductVistorDao.loadData()

.distinct()

.map()

.filter()

.handle()

** .subscribe();**

;//加载最新的商品浏览数据

 

2、Reactor Core

1、HttpHandler、HttpServer

   public static void main(String[] args) throws IOException {//快速自己编写一个能处理请求的服务器
​//1、创建一个能处理Http请求的处理器。 参数:请求、响应; 返回值:Mono<Void>:代表处理完成的信号HttpHandler handler = (ServerHttpRequest request,ServerHttpResponse response)->{URI uri = request.getURI();System.out.println(Thread.currentThread()+"请求进来:"+uri);//编写请求处理的业务,给浏览器写一个内容 URL + "Hello~!"
//            response.getHeaders(); //获取响应头
//            response.getCookies(); //获取Cookie
//            response.getStatusCode(); //获取响应状态码;
//            response.bufferFactory(); //buffer工厂
//            response.writeWith() //把xxx写出去
//            response.setComplete(); //响应结束
​//数据的发布者:Mono<DataBuffer>、Flux<DataBuffer>
​//创建 响应数据的 DataBufferDataBufferFactory factory = response.bufferFactory();
​//数据BufferDataBuffer buffer = factory.wrap(new String(uri.toString() + " ==> Hello!").getBytes());
​
​// 需要一个 DataBuffer 的发布者return response.writeWith(Mono.just(buffer));};
​//2、启动一个服务器,监听8080端口,接受数据,拿到数据交给 HttpHandler 进行请求处理ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(handler);
​
​//3、启动Netty服务器HttpServer.create().host("localhost").port(8080).handle(adapter) //用指定的处理器处理请求.bindNow(); //现在就绑定
​System.out.println("服务器启动完成....监听8080,接受请求");System.in.read();System.out.println("服务器停止....");
​
​}

3、DispatcherHandler

SpringMVC: DispatcherServlet;

SpringWebFlux: DispatcherHandler

1、请求处理流程

  • HandlerMapping:请求映射处理器; 保存每个请求由哪个方法进行处理

  • HandlerAdapter:处理器适配器;反射执行目标方法

  • HandlerResultHandler:处理器结果处理器;

SpringMVC: DispatcherServlet 有一个 doDispatch() 方法,来处理所有请求;

WebFlux: DispatcherHandler 有一个 handle() 方法,来处理所有请求;

public Mono<Void> handle(ServerWebExchange exchange) { if (this.handlerMappings == null) {return createNotFoundError();}if (CorsUtils.isPreFlightRequest(exchange.getRequest())) {return handlePreFlight(exchange);}return Flux.fromIterable(this.handlerMappings) //拿到所有的 handlerMappings.concatMap(mapping -> mapping.getHandler(exchange)) //找每一个mapping看谁能处理请求.next() //直接触发获取元素; 拿到流的第一个元素; 找到第一个能处理这个请求的handlerAdapter.switchIfEmpty(createNotFoundError()) //如果没拿到这个元素,则响应404错误;.onErrorResume(ex -> handleDispatchError(exchange, ex)) //异常处理,一旦前面发生异常,调用处理异常.flatMap(handler -> handleRequestWith(exchange, handler)); //调用方法处理请求,得到响应结果}
  • 1、请求和响应都封装在 ServerWebExchange 对象中,由handle方法进行处理

  • 2、如果没有任何的请求映射器; 直接返回一个: 创建一个未找到的错误; 404; 返回Mono.error;终结流

  • 3、跨域工具,是否跨域请求,跨域请求检查是否复杂跨域,需要预检请求;

  • 4、Flux流式操作,先找到HandlerMapping,再获取handlerAdapter,再用Adapter处理请求,期间的错误由onErrorResume触发回调进行处理;

源码中的核心两个:

  • handleRequestWith: 编写了handlerAdapter怎么处理请求

  • handleResult: String、User、ServerSendEvent、Mono、Flux ...

concatMap: 先挨个元素变,然后把变的结果按照之前元素的顺序拼接成一个完整流

private <R> Mono<R> createNotFoundError() {Exception ex = new ResponseStatusException(HttpStatus.NOT_FOUND);return Mono.error(ex);}
Mono.defer(() -> {Exception ex = new ResponseStatusException(HttpStatus.NOT_FOUND);return Mono.error(ex);}); //有订阅者,且流被激活后就动态调用这个方法; 延迟加载;

4、注解开发

1、目标方法传参

Method Arguments :: Spring Framework

Controller method argumentDescription
ServerWebExchange封装了请求和响应对象的对象; 自定义获取数据、自定义响应
ServerHttpRequest, ServerHttpResponse请求、响应
WebSession访问Session对象
java.security.Principal
org.springframework.http.HttpMethod请求方式
java.util.Locale国际化
java.util.TimeZone + java.time.ZoneId时区
@PathVariable路径变量
@MatrixVariable矩阵变量
@RequestParam请求参数
@RequestHeader请求头;
@CookieValue获取Cookie
@RequestBody获取请求体,Post、文件上传
HttpEntity<B>封装后的请求对象
@RequestPart获取文件上传的数据 multipart/form-data.
java.util.Map, org.springframework.ui.Model, and org.springframework.ui.ModelMap.Map、Model、ModelMap
@ModelAttribute
Errors, BindingResult数据校验,封装错误
SessionStatus + class-level @SessionAttributes
UriComponentsBuilderFor preparing a URL relative to the current request’s host, port, scheme, and context path. See URI Links.
@SessionAttribute
@RequestAttribute转发请求的请求域数据
Any other argument所有对象都能作为参数:1、基本类型 ,等于标注@RequestParam 2、对象类型,等于标注 @ModelAttribute

2.返回值写法

sse和websocket区别:

  • SSE:单工;请求过去以后,等待服务端源源不断的数据

  • websocket:双工: 连接建立后,可以任何交互;

Controller method return valueDescription
@ResponseBody把响应数据写出去,如果是对象,可以自动转为json
HttpEntity<B>, ResponseEntity<B>ResponseEntity:支持快捷自定义响应内容
HttpHeaders没有响应内容,只有响应头
ErrorResponse快速构建错误响应
ProblemDetailSpringBoot3;
String就是和以前的使用规则一样;forward: 转发到一个地址redirect: 重定向到一个地址配合模板引擎
View直接返回视图对象
java.util.Map, org.springframework.ui.Model以前一样
@ModelAttribute以前一样
Rendering新版的页面跳转API; 不能标注 @ResponseBody 注解
void仅代表响应完成信号
Flux<ServerSentEvent>, Observable<ServerSentEvent>, or other reactive type使用 text/event-stream 完成SSE效果
Other return values未在上述列表的其他返回值,都会当成给页面的数据;

 

5、文件上传

Multipart Content :: Spring Framework

class MyForm {
​private String name;
​private MultipartFile file;
​// ...
​
}
​
@Controller
public class FileUploadController {
​@PostMapping("/form")public String handleFormUpload(MyForm form, BindingResult errors) {// ...}
​
}
现在@PostMapping("/")
public String handle(@RequestPart("meta-data") Part metadata, @RequestPart("file-data") FilePart file) { // ...
}

6、错误处理

 @ExceptionHandler(ArithmeticException.class)public String error(ArithmeticException exception){System.out.println("发生了数学运算异常"+exception);
​//返回这些进行错误处理;
//        ProblemDetail:  建造者:声明式编程、链式调用
//        ErrorResponse : 
​return "炸了,哈哈...";}

7、RequestContext

8、自定义Flux配置

WebFluxConfigurer

容器中注入这个类型的组件,重写底层逻辑

@Configuration
public class MyWebConfiguration {
​//配置底层@Beanpublic WebFluxConfigurer webFluxConfigurer(){
​return new WebFluxConfigurer() {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedHeaders("*").allowedMethods("*").allowedOrigins("localhost");}};}
}

9、Filter

@Component
public class MyWebFilter implements WebFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {ServerHttpRequest request = exchange.getRequest();ServerHttpResponse response = exchange.getResponse();
​System.out.println("请求处理放行到目标方法之前...");Mono<Void> filter = chain.filter(exchange); //放行
​
​//流一旦经过某个操作就会变成新流
​Mono<Void> voidMono = filter.doOnError(err -> {System.out.println("目标方法异常以后...");}) // 目标方法发生异常后做事.doFinally(signalType -> {System.out.println("目标方法执行以后...");});// 目标方法执行之后
​//上面执行不花时间。return voidMono; //看清楚返回的是谁!!!}
}

这篇关于Spring Webflux 详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/781929

相关文章

Java获取当前时间String类型和Date类型方式

《Java获取当前时间String类型和Date类型方式》:本文主要介绍Java获取当前时间String类型和Date类型方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录Java获取当前时间String和Date类型String类型和Date类型输出结果总结Java获取

C语言进阶(预处理命令详解)

《C语言进阶(预处理命令详解)》文章讲解了宏定义规范、头文件包含方式及条件编译应用,强调带参宏需加括号避免计算错误,头文件应声明函数原型以便主函数调用,条件编译通过宏定义控制代码编译,适用于测试与模块... 目录1.宏定义1.1不带参宏1.2带参宏2.头文件的包含2.1头文件中的内容2.2工程结构3.条件编

Spring Boot Actuator应用监控与管理的详细步骤

《SpringBootActuator应用监控与管理的详细步骤》SpringBootActuator是SpringBoot的监控工具,提供健康检查、性能指标、日志管理等核心功能,支持自定义和扩展端... 目录一、 Spring Boot Actuator 概述二、 集成 Spring Boot Actuat

OpenCV在Java中的完整集成指南分享

《OpenCV在Java中的完整集成指南分享》本文详解了在Java中集成OpenCV的方法,涵盖jar包导入、dll配置、JNI路径设置及跨平台兼容性处理,提供了图像处理、特征检测、实时视频分析等应用... 目录1. OpenCV简介与应用领域1.1 OpenCV的诞生与发展1.2 OpenCV的应用领域2

在Java中使用OpenCV实践

《在Java中使用OpenCV实践》用户分享了在Java项目中集成OpenCV4.10.0的实践经验,涵盖库简介、Windows安装、依赖配置及灰度图测试,强调其在图像处理领域的多功能性,并计划后续探... 目录前言一 、OpenCV1.简介2.下载与安装3.目录说明二、在Java项目中使用三 、测试1.测

PyTorch中的词嵌入层(nn.Embedding)详解与实战应用示例

《PyTorch中的词嵌入层(nn.Embedding)详解与实战应用示例》词嵌入解决NLP维度灾难,捕捉语义关系,PyTorch的nn.Embedding模块提供灵活实现,支持参数配置、预训练及变长... 目录一、词嵌入(Word Embedding)简介为什么需要词嵌入?二、PyTorch中的nn.Em

Python Web框架Flask、Streamlit、FastAPI示例详解

《PythonWeb框架Flask、Streamlit、FastAPI示例详解》本文对比分析了Flask、Streamlit和FastAPI三大PythonWeb框架:Flask轻量灵活适合传统应用... 目录概述Flask详解Flask简介安装和基础配置核心概念路由和视图模板系统数据库集成实际示例Stre

Spring Bean初始化及@PostConstruc执行顺序示例详解

《SpringBean初始化及@PostConstruc执行顺序示例详解》本文给大家介绍SpringBean初始化及@PostConstruc执行顺序,本文通过实例代码给大家介绍的非常详细,对大家的... 目录1. Bean初始化执行顺序2. 成员变量初始化顺序2.1 普通Java类(非Spring环境)(

Spring Boot 中的默认异常处理机制及执行流程

《SpringBoot中的默认异常处理机制及执行流程》SpringBoot内置BasicErrorController,自动处理异常并生成HTML/JSON响应,支持自定义错误路径、配置及扩展,如... 目录Spring Boot 异常处理机制详解默认错误页面功能自动异常转换机制错误属性配置选项默认错误处理

java如何实现高并发场景下三级缓存的数据一致性

《java如何实现高并发场景下三级缓存的数据一致性》这篇文章主要为大家详细介绍了java如何实现高并发场景下三级缓存的数据一致性,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 下面代码是一个使用Java和Redisson实现的三级缓存服务,主要功能包括:1.缓存结构:本地缓存:使