14.4、SpringWebFlux-1

news2024/11/24 17:17:55

14.4、SpringWebFlux-1

14.4.1、前置知识

SpringMVCSpringBootMavenJava8 新特性

14.4.2、基本介绍

官方文档

Web on Reactive Stack (spring.io)


  • Spring5 添加新的模块,用于 web 开发的,功能 SpringMVC 类似的,WebFlux 使用当前一种比较流程响应的编程出现的框架

  • 使用传统 web 框架,比如 SpringMVC,这些基于 Servlet 容器, WebFlux 是一种异步非阻塞的框架,异步非阻塞的框架在 Servlet3.1 以后才支持。核心是基于 Reactor 的相关 API 实现的

  • 什么是异步非阻塞

    • 异步和同步
      • 针对调用者,调用者发请求,
      • 若等着对方回应之后才去做其他事情就是同步,
      • 若发送请求之后才不等着对方回应就去做其他事情就是异步
    • 非阻塞与阻塞
      • 针对被调用者
      • 被调用者收到请求之后,做完了请求任务之后才给出反馈就是阻塞(阻塞了调用者,等待被调用者处理完成)
      • 收到请求之后马上给出反馈然后再去做事情就是非阻塞
    • 例如:
      • 面试完在家等着面试结构就是同步,面试完之后去另一家公司面试就是异步。
      • 面试完之后让回家等候通知就是阻塞,面试完之后直接通知你结果就是非阻塞
  • 特点:

    • 非阻塞式:在有限的资源下,提高系统的吞吐量和伸缩性,以 Reactor 为基础实现响应式编程
    • 函数式编程:Spring5 框架基于 java8WebFlux 使用 Java8 函数式编程方式实现路由请求

比较 SpringMVC

image-20221117204114765

  • 第一:两个框架都可以使用注解方式,都运行在 Tomcat 容器中
  • 第二:SpringMVC 采用命令式编程,WebFlux 采用异步响应式

14.4.2、响应式编程

14.4.2.1、什么是响应式编程

[响应式编程](响应式编程_百度百科 (baidu.com))是一种面向数据流和变化传播的编程范式。

  • 这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。

  • 电子表格程序就是响应式编程的一个例子。单元格可以包含字面值或类似"=B1+C1"的公式,而包含公式的单元格的值会依据其他单元格的值的变化而变化。

image-20221117210049351


14.4.2.2、Java8 及其之前版本

  • 提供的观察者模式的两个类 ObserverObservable
import java.util.Observable;
public class ObserverDemo extends Observable {
    public static void main(String[] args) {
        ObserverDemo data = new ObserverDemo();
        //添加观察者
        data.addObserver((o, a) -> {
            System.out.println("发生了变化:" + a);
        });
        //添加观察者
        data.addObserver((o, a) -> {
            System.out.println("收到被观察者通知,准备改变:" + a);
        });
        data.setChanged();//数据变化
        data.notifyObservers("hello");//通知
        data.clearChanged();
    }
}

测试结果

image-20221117212919240

14.4.2.3、Java9 及其之后

发布订阅

image-20221117215259805

Publisher

Publisher函数式接口,负责发布数据。Publisher中函数subscribe负责绑定Subscriber

    //Publisher是函数式接口,负责发布数据。
    //发布者
    @FunctionalInterface
    public static interface Publisher<T> {

        //Publisher中函数subscribe负责绑定Subscriber
        public void subscribe(Subscriber<? super T> subscriber);
    }

Subscriber

Subscriber是静态内部接口,负责订阅消费数据。Subscriber中定义四个方法,分别是onSubscribeonNextonErroronComplete,这四个方法会在相应情况下触发

  • onSubscribe;订阅成功后触发,并且表明可以开始接收订阅数据了
  • onNext:获取接受数据的下一项
  • onError:在发布者或订阅遇到错误时触发
  • onComplete:接受完所有的数据后触发
   //订阅者
    public static interface Subscriber<T> {
        public void onSubscribe(Subscription subscription);

        public void onNext(T item);

       
        public void onError(Throwable throwable);

       
        public void onComplete();
    }

Subscription

Subscription关联PublisherSubscriber,表示PublisherSubscriber的订阅关系。Subscription使用requestcancel方法管理PublisherSubscriber的消费

  • request:请求获取数据的次数
  • cancel:取消订阅,订阅者不在接受数据
	public static interface Subscription {
        
        public void request(long n);

       
        public void cancel();
    }


Processor

Processor继承了PublisherSubscriber接口,表示既是生产者,又是订阅者的特殊对象。Processor一般作为数据的中转处理站, 将数据处理之后发给下个订阅者

public final class Flow {

    private Flow() {} // 不可实例化






    
    public static interface Processor<T,R> extends Subscriber<T>, Publisher<R> {
    }

    static final int DEFAULT_BUFFER_SIZE = 256;

    public static int defaultBufferSize() {
        return DEFAULT_BUFFER_SIZE;
    }

}

14.4.2.4、Reactor实现

  • 响应式编程操作中,Reactor 满足 Reactive 规范
  • Reactor 有两个核心类,MonoFlux,这两个类都实现接口 Publisher,提供了丰富操作符。
    • Flux 对象实现发布者,返回 N 个元素;
    • Mono 实现发布者,返回 0 0 0 或者 1 1 1 个元素
  • FluxMono 都是数据流的发布者,使用 FluxMono 都可以发出三种数据信号
    • 元素值、错误信号、完成信号
    • 错误信号和完成信号都代表终止信号。
      • 终止信号用于告诉订阅者数据流结束了
      • 错误信号终止数据流,同时把错误信息传递给订阅者

image-20221117222927105


引入响相应的依赖

<dependency>
    <groupId>io.projectreactor</groupId>
    <artifactId>reactor-core</artifactId>
    <version>3.1.5.RELEASE</version>
</dependency>

编写代码

public class TestReactor {
    public static void main(String[] args) {
        //just方法直接声明(就是发布者发布了一些数据)
        Flux.just(1, 2, 3, 4);
        Mono.just(1);

        //其他的方法
        Integer[] arr = new Integer[]{1, 2, 3, 4};
        Flux.fromArray(arr);

        //声明集合
        List<Integer> list = Arrays.asList(arr);
        Flux.fromIterable(list);

        //声明流
        Flux.fromStream(list.stream());
    }
}

没有订阅者,是不会输出的。

  • 调用 just 或者其他方法只是声明数据流,数据流并没有发出,只有进行订阅之后才会触发数据流。

1.声明订阅者

  • public class TestReactor {
        public static void main(String[] args) {
            //just方法直接声明(就是发布者发布了一些数据),接收者进行消费
            Flux.just(1, 2, 3, 4).subscribe(System.out::println);
            Mono.just(1).subscribe(System.out::println);
    

2.输出结果

  • image-20221117224706133

14.4.2.5、三种信号特点

  • 错误信号和完成信号都是终止信号,不能共存的
  • 若没有发送任何元素值,而是直接发送错误或者完成信号,表示是空数据流
  • 若没有错误信号,没有完成信号,表示是无限数据流

例如:

public class TestReactor {
    public static void main(String[] args) {
        //错误信号
        Flux.error(new RuntimeException());
    }
}

14.4.2.6、操作符

对数据流进行一道道操作,称为操作符,不如工厂的流水线

就和 stream 流一样

第一 map

  • 元素映射为新元素

image-20221117230433825

第二 flatMap

  • 元素映射为流

  • 把每个元素先变成一个流,把每个流封装成一个大流返回

  • 例如:stream 中的 flatmap

    Integer[] arr = new Integer[]{1, 2, 3, 4};
    //声明集合
    List<Integer> list = Arrays.asList(arr);
    Stream<Integer> integerStream = list.stream().flatMap((map) -> {
        return Stream.of(map + 1);
    });
    

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络热传App鉴定 |「得物」疑私删用户视频?从技术角度还原事件始末

声明&#xff1a;本文更注重于原理知识的普及&#xff0c;因此文中不会有大量实际代码的展示&#xff0c;如果想从代码层面上了解「应用存储分区」的内容&#xff0c;欢迎阅读我两年前写过的技术文章《Android 10 应用分区存储适配实践》 近日&#xff0c;有网友爆料&#xff0…

MySQL 分库分表

MySQL分库分表 概念 读写分离优化了互联网读多写少场景下的性能问题&#xff0c;考虑一个业务场景&#xff0c;如果读库的数据规模非常大&#xff0c;除了增加多个从库之外&#xff0c;还有其他的手段吗&#xff1f;实现数据库高可用&#xff0c;还有另外一个撒手锏&#xff…

Python性能优化指南--让你的Python代码快x3倍的秘诀

Python性能优化指南 Python最为人诟病的就是其执行速度。如何让Python程序跑得更快一直是Python核心团队和社区努力的方向。作为Python开发者&#xff0c;我们同样可以采用某些原则和技巧&#xff0c;写出性能更好的Python代码。本文将带大家深入探讨Python程序性能优化方法。…

99页4万字XX大数据湖项目建设方案

目 录 1. 项目综述 1.1. 项目背景 1.2. 项目目标 1.3. 项目建设路线 2 需求分析 2.1功能需求 2.1.1 统一数据接入 2.1.2 数据迁移 2.1.3 数据范围与ETL 2.1.4 报表平台 2.1.5 安全管理 2.1.6 数据治理 2.2非功能需求 2.2.1运维保障需求 2.2.2可用性需求 2.2.3可…

MQTT 具备那些特征?

目录 1、MQTT 中的 QoS&#xff08;消息服务质量&#xff09; &#xff08;1&#xff09;为什么服务质量&#xff08;QoS&#xff09;很重要? &#xff08;2&#xff09;QoS 在 MQTT 中是如何工作的? &#xff08;3&#xff09;如何选择正确的 QoS 级别 &#xff08;4&a…

Java开发中Word转PDF文件5种方案横向评测

Java开发中Word转PDF文件5种方案横向评测 前段时间接了个项目&#xff0c;需要各种处理Word模板、转PDF、签章等等&#xff0c;非常头疼&#xff0c;其中光是一个word转PDF就折磨我好久&#xff0c;实现转换很简单&#xff0c;但是效果总是达不到满意&#xff0c;于是我把市面…

【Linux】关于普通用户无法使用sudo指令的解决方案

文章目录前言解决方案结语前言 在这篇博客中&#xff0c;测试 rm -rf 删除文件时无视权限暴力删除的效果时&#xff0c;使用了 sudo 指令。 但是sudo指令是不能直接使用的&#xff0c;需要修改一些设置。 当时我遇到这个问题时&#xff0c;困惑了许久&#xff0c;查找解决方…

JVM执行引擎

文章目录学习资料执行引擎概述工作过程Java代码编译和执行的过程什么是解释器&#xff08;Interpreter&#xff09;&#xff0c;什么是JIT编译器&#xff1f;为什么说Java是半编译半解释型语言&#xff1f;机器码、指令、汇编语言、高级语言机器码指令指令集汇编语言高级语言字…

UE5实现PS图层样式投影效果

一、PS图层样式投影效果 1、创建材质函数 MF_PS_Style_Shadow 公开到库&#xff08;可选&#xff09; 定义 function input。 Shadow代码&#xff1a; /** PS图层样式投影效果param {UVs} texture coordinateparam {TextureObject} texture objectparam {TextureSize} …

十、children的深入用法-React.Children对象上的方法

目标 理解什么是children掌握React.Children对象上的方法 知识点 什么是children上图中我们看到了&#xff0c;我们之前学过的React.createElement方法&#xff0c;现在大家发现jsx的内容&#xff0c;全部都体现在了该方法上&#xff1b;那么React.createElement其实是有三个…

专精特新企业数据集两份数据

专精特新企业数据集 一、三批专精特新上市、非上市公司数据分布 1、时间截止至2021年8月 2、区域范围&#xff1a;上市和非上市公司两大板块&#xff0c;涵盖申万一级行业 3、指标说明&#xff1a; 包含如下内容&#xff1a;专精特新上市公司名单汇总、第一批专精特新上市公…

opencv 入门学习

opencv 演示 输入说明 原图在顶层后然后再去按键&#xff0c;不然会失效&#xff08;未知原因&#xff09; 1.roberts 边缘检测 2.sobel算子 3.Canny算子 4.Laplace算子 5.Canny算子&#xff0c;轮廓显示 空格 人脸检测准备一张图片效果 默认显示原图和灰阶图 roberts 边缘…

MySQL版本号6和7去哪了

问题 MySQL版本号6和7去哪了 详细问题 笔者起初误以为MySQL版本号6和7可能由于存在诟病不受欢迎或由于MySQL版本迭代过快导致未能在市场上流行 但是在浏览MySQL官网注意到 MySQL在2017年发布了新的版本8.0,但是在此之前的上一一个版本是5.7,40&#xff0c;那么中间的6和7去哪…

并发编程永远绕不开的难题,跟着大牛带你Java并发编程从入门到精通

我们知道&#xff0c;很多框架或者自研组件的底层&#xff0c;都或多或少涉及到并发编程方面的技术点。 比如&#xff1a;在一些本地缓存组件中&#xff0c;当本地缓存过期后&#xff0c;需要从数据库加载数据&#xff0c;这个阶段中就会涉及到线程并发请求的处理&#xff1b;在…

微信小程序云开发

概念 小程序云开发&#xff0c;让前端程序员拥有后端的能力云函数 &#xff08;nodejs&#xff09;云数据库 &#xff08;mogodb&#xff09;云存储前端写好云函数 > 上传到云服务器 >实现自定云部署前端去调用云函数>间接通过云函数对数据库的操作前端>全栈 注意…

DSP之寄存器映射和CDM文件

DSP之寄存器映射和CDM文件 RAM&#xff1a;程序运行速度快&#xff0c;关掉电源&#xff0c;程序会丢失。 Flash&#xff1a;程序运行速度慢&#xff0c;关掉电源&#xff0c;程序不会丢失。 所以&#xff0c;程序一般存到Flash中&#xff0c;在运行的时候&#xff0c;由CPU将…

2010-2019年208个地级市城乡收入差距泰尔指数

2010-2019年208个地级市城乡收入差距泰尔指数 1、数据来源&#xff1a;各省的统计NJ以及部分地级市的NJ&#xff08;主要是地级市的城镇化率&#xff09; 城镇化率为常驻人口城镇化率而非户籍人口城镇化率。附件中也包含各个地级市的城镇化率&#xff0c;农村人均可支配收入2…

Linux开发工具(1)——yum

文章目录软件包管理器 —— yum安装软件的三个问题Linux开源生态yum查找软件yum下载软件yum删除软件配置yum源Linux下的工具本质也是指令 , 下面我会介绍几个常用的工具 , 分别是yum(相当于是手机上的应用商店 , 可以在里面下载工具 ) vim&#xff08;多模式编辑器&#xff09;…

【毕业设计】深度学习行人车辆流量计数系统 - 目标检测 python

文章目录0 前言1. 目标检测概况1.1 什么是目标检测&#xff1f;1.2 发展阶段2. 行人检测2.1 行人检测简介2.2 行人检测技术难点2.3 行人检测实现效果2.4 关键代码-训练过程3 最后0 前言 &#x1f525; Hi&#xff0c;大家好&#xff0c;这里是丹成学长的毕设系列文章&#xff…

机器学习-SVM算法

文章目录支持向量机1. 间隔与支持向量1.1. 点到超平面的距离1.2. 去掉绝对值1.3. 最大间隔2. 对偶问题2.1. 引入拉格朗日乘子2.2. 求偏导2.3. 得到对偶问题2.4. 求解内层函数 minw,bL(w,b,α)min_{w,b} L(w,b,\alpha)minw,b​L(w,b,α)2.5. 求解外层函数 maxαminw,bL(w,b,α)m…