再临SpringBoot——WebFlux处理流程

2023-11-12


SpringMvc通常是Servlet应用,因此,可能被当前线程阻塞。以远程调用为例,由于阻塞的缘故,导致Servlet容器使用较大的线程池处理请求。而Spring WebFlux通常是非阻塞的服务(同步/异步无法确定,Reactor默认同步,可改为异步),不会发生阻塞,因此该阻塞服务器可使用少量、固定大小的线程池处理请求。(非阻塞无非就是当前不阻塞,后续去回调。)

WebFlux初次尝试

import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;

@SpringBootApplication
public class DemoApplication {

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

    @Bean
    public RouterFunction<ServerResponse> routerFunction(){
        return route(GET("/hello"),this::hello);
    }

    public Mono<ServerResponse> hello(ServerRequest serverRequest){
        return ServerResponse.status(HttpStatus.OK)
                .body(Mono.just("hello world"),String.class);
    }

}

启动项目后,通过访问"localhost:8080/hello"就可以得到返回值"hello world"。
这个过程中,需要注意这五个类及其方法:

  • 路由方法:RouterFunction#route
  • 请求判定:RequestPredicate(类似于Predicate)
  • 处理函数:HandlerFunction
  • 请求接口:ServerRequest
  • 响应接口:ServerResponse

处理过程源码分析

传入的请求被路由到有RouterFunction<T>的处理函数(即Function<Request, Optional<HandlerFunction<T>>)路由到处理函数,如果它匹配的话;否则就返回一个空的结果。路由方法与@RequestMapping注解的作用相似。但是,还有一个显著的区别:用注解时路由会被限制到注解的value所能表达的范围,处理这些方法的覆盖是困难的(除非用@profile注解);当用路由方法的时候,代码就在那里,可以轻松的覆盖或替换。

@Configuration
public class PersonRouter {
  // solution
  @Bean
  public RouterFunction<ServerResponse> peopleRoutes(PersonHandler personHandler) {
    return RouterFunctions.route(GET("/people/{id}").and(accept(APPLICATION_JSON)), personHandler::get)
        .andRoute(GET("/people").and(accept(APPLICATION_JSON)), personHandler::all)
        .andRoute(POST("/people").and(accept(APPLICATION_JSON)).and(contentType(APPLICATION_JSON)), personHandler::post)
        .andRoute(PUT("/people/{id}").and(accept(APPLICATION_JSON)).and(contentType(APPLICATION_JSON)), personHandler::put)
        .andRoute(DELETE("/people/{id}"), personHandler::delete)
        .andRoute(GET("/people/country/{country}").and(accept(APPLICATION_JSON)), personHandler::getByCountry);
  }
}

路由函数的组合 如果第一个RountHandler 匹配不成功,则进入的下一个RountHandler,匹配顺序按代码顺序执行。

静态引入RouterFunctions.route(),这样就可以用请求判断式(RequestPredicate) (即 Predicate<Request>)和处理方法(HandlerFunction)创建路由方法了,其java源码如下:

public static <T extends ServerResponse> RouterFunction<T> route(RequestPredicate predicate, HandlerFunction<T> handlerFunction) {
        return new RouterFunctions.DefaultRouterFunction(predicate, handlerFunction);
    }

再来看看Predicate的源码:

@FunctionalInterface
public interface RequestPredicate {
    boolean test(ServerRequest var1);
    ...default method...
   }

可以知道RequestPredicate其实就是一个返回布尔值的方法参数。如果判断式判断成功则返回处理方法,否则返回空结果

这一新框架的起点是HandlerFunction<T>,基本上是Function<Request, Response<T>>,其源码如下:

@FunctionalInterface
public interface HandlerFunction<T extends ServerResponse> {
    Mono<T> handle(ServerRequest var1);
}

可以看到,HandlerFunction接受ServerRequest类型的参数,返回Mono包装的ServerResponse类型的返回值。一个简单的“Hello World”处理函数的例子,返回有200状态以及body为String的响应消息:

HandlerFunction<String> helloWorld =
 request -> Response.ok().body(fromObject("Hello World"));

正如我们在上面的例子中看到的,处理函数是通过构建在Reactor的基础上而完全响应:它们接受Flux,Mono,或任何其他相应的流Publisher作为响应类型。要注意的一点,HandlerFunction本身是没有副作用的,因为它返回响应,而不是把它当作一个参数(参见Servlet.service(ServletRequest,ServletResponse),这实质上是BiConsumer<ServletRequest,ServletResponse> )。没有副作用有很多好处:易于测试,编写和优化。

ServerRequest并且ServerResponse接口可以提供JDK-8(Lambda)对底层HTTP消息的友好访问。
函数式端点组件请求流程处理:
在这里插入图片描述
注解驱动组件流程请求处理:
在这里插入图片描述

WebFlux 示例程序

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

再临SpringBoot——WebFlux处理流程 的相关文章

随机推荐

  • android卡刷包自制rom之添加删除,添加/删除ROM内置APP的教程

    ROM闪存软件包是Android闪存中必不可少的东西删除刷机包自带软件 但是大多数ROM闪存软件包都与许多应用程序集成在一起 其中许多不是您想要的 也没有您想要的应用程序 使用Mushroom ROM Assistant快速删除和添加APK
  • 偏最小二乘法(PLS)计算流程

    根据相关文献 将PLS的计算流程整理如下 供大家参考 1 输入样本矩阵X 输出值矩阵Y分别对X Y进行中心化处理 归一化方差 得到矩阵 E0和F 2 令n 0 3 计算矩阵En FF En 计算En FF En的最大特征根对应的单位特征向量
  • AndroidStudio会在@NonNull后面自动添加@org.jetbrains.annotations.Nullable

    今天呀在AndroidStudio 4 1中一直有个问题困扰着我 那就是AndroidStudio会在 NonNull后面自动添加 org jetbrains annotations Nullable 这 自动添加就算了还报错 每次都要删除
  • 区块链搬砖实战

    前言 相信不少币友在数字货币交易的时候都发现了 不同的交易平台不同的数字货币都存在一定的差价 这时候就引出了 搬砖的概念 搬砖的概念 由于各种因素导致各平台的虚拟货币的价格有价格差 产生了套利空间 运用平台之间价格差来谋求利益的行为俗称 搬
  • vs code终端修改字体大小以及其它样式

    1 在文件 gt 首选项 gt 设置 2 用户 gt 工作台 gt 找到settings json点击进入 3 在 settings json文件里添加需要修改的样式 terminal integrated cursorBlinking t
  • 软件资源下载链接

    1 Dreamweaver DW cs5 链接 https pan baidu com s 1kVqqpqJ 密码 9hc4 DW cc2014 链接 https pan baidu com s 1skQvBCL 密码 3kd8 DW cc
  • 数据库系统——复习总结

    数据库系统
  • cvCanny检测边缘,连通重要的非连通区域

    这个函数就是使用canny边缘检测算子检测图象的边缘 在opencv下使用这个函数之前最好将图象平滑处理一下 要不然可能检测不到边缘 检测到的边缘 这些边缘大多还不是连通区域 可以通过3 3的模板将一些相近的边缘连接起来 也可以用cvDil
  • Tesseract-OCR的配置和应用

    1 百度搜索Tesseract OCR下载 Tesseract orc setup 3 02 02 exe 要记得自己的安装目录 博主的安装路径为 C Program Files x86 Tesseract OCR 等会配置环境变量要用 如
  • C# Selenium chromedriver 隐藏Devtool控制台窗口

    爬取网页信息时 使用了C Selenium WebDriver dll chromedriver Chrome 除了chromedriver控制台窗口 可以通过CDS HideCommandPromptWindow true隐藏 还有出现一
  • Health Kit基于数据提供专业方案,改善用户睡眠质量

    什么是CBT I 中国社科院等机构今年发布的 中国睡眠研究报告2023 内容显示 2022年 受访者的每晚平均睡眠时长为7 40小时 近半数受访者的每晚平均睡眠时长不足8小时 47 55 16 79 的受访者的每晚平均睡眠时长不足7小时 这
  • C++异常处理机制(超级详细)

    目录 0 异常处理机制简介 1 传统错误处理机制 通过函数返回值 2 异常处理机制语法 3 异常接口声明 4 异常类型和声明周期 4 1throw基本类型异常 int float char 4 2throw字符串类型异常 4 3throw类
  • 数据可视化(学会用matplotlib绘图)

    1 绘制简单的折线图 import matplotlib pyplot as plt squres 1 4 9 16 25 plt plot squres 把列表传给plot 这个函数尝试根据这些数字绘制出有意义的图形 plt show 打
  • 【取模软件PCtoLCD2002使用教程】

    1 打开取模软件PCtoLCD 2 左上角模式选择为字符模式 3 点击选项 4 设置如下 然后点击确定 5 以16x16汉字取模为例 字宽字高都改为16 然后在输入栏输入汉字 点击生成字模生成的字模如下 然后将字模复制到例程lcdfont
  • 距离向量算法_RIP协议及距离向量算法(上)【44】

    1 RIP协议 RIP 全称Routing Information Protocol 即路由信息协议 RIP是一种分布式的基于距离向量的路由选择协议 是因特网的协议标准 最大优点的简单 RIP协议要求网络中每一个路由器都维护从它自己到其它每
  • Centos 安装mysql8(YUM方式)

    1 执行安装命令 root localhost wget https dev mysql com get mysql80 community release el8 4 noarch rpm root localhost yum modul
  • JAVA 定义静态map并赋值

    private static final Map
  • C语言入门经典三,c语言入门经典第4版和第3版有什么区别

    问 微软的C语言和其他C语言有什么区别吗 答 不知道楼主说的是所谓 微软的c 是指什么概念 个人意见 仅供参考 1 如果是指微软推出的c语言的编译器ms c的话 其实就是c语言各个编译器之间的区别 如果你想深入了解 最好是学习下c标准的制定
  • 【ICS大作业】

    零 摘要 本文对给定的hello程序的生命周期进行了系统性分析 程序经预处理生成hello i 编译生成hello s 汇编生成hello o 最后链接成可执行目标文件hello Shell收到 hello的指令 调用fork函数创建进程
  • 再临SpringBoot——WebFlux处理流程

    文章目录 WebFlux初次尝试 处理过程源码分析 SpringMvc通常是Servlet应用 因此 可能被当前线程阻塞 以远程调用为例 由于阻塞的缘故 导致Servlet容器使用较大的线程池处理请求 而Spring WebFlux通常是非