spring-boot-webflux-demo-反应式接口

webflux + springboot 整合(史上最全) 前言 webmvc和webflux作为spring framework的两个重要模块,代表了两个IO模型,阻塞式和非阻塞式的。 webmvc是基于servlet的阻塞式模型(一般称为oio),一个请求到达服务器后会单独分配一个线程去处理请求,如果请求包含IO操作,线程在IO操作结束之前一直处于阻塞等待状态,这样线程在等待IO操作结束的时间就浪费了。 webflux是基于reactor的非阻塞模型(一般称为nio),同样,请求到达服务器后也会分配一个线程去处理请求,如果请求包含IO操作,线程在IO操作结束之前 阅读详情

Spring Framework 5包含一个新 spring-webflux 模块。该模块包含对反应式HTTP和WebSocket客户端的支持以及反应式服务器Web应用程序(包括REST,HTML浏览器和WebSocket样式交互)
spring web-flux 支持2种不同的编程模型

  1. 支持Spring MVC @Controller 这种注解,用法大同小异
  2. 函数式 Java 8 lambda 风格的路由函数处理请求

Spring WebFlux 是 Spring Framework 5.0中引入的新的响应式web框架。与Spring MVC不同,它不需要Servlet API,是完全异步且非阻塞的,并且通过Reactor项目实现了Reactive Streams规范。
Spring WebFlux 用于创建基于事件循环执行模型的完全异步且非阻塞的应用程序。
(PS:异步非阻塞是针对服务端而言的,服务端可以充分利用CPU资源去做更多事情,与客户端无关,客户端该怎么请求还是怎么请求。)
Reactive Streams是一套用于构建高吞吐量、低延迟应用的规范。而Reactor项目是基于这套规范的实现,它是一个完全非阻塞的基础,且支持背压。Spring WebFlux基于Reactor实现了完全异步非阻塞的一套web框架,是一套响应式堆栈。
【spring-webmvc + Servlet + Tomcat】命令式的、同步阻塞的
【spring-webflux + Reactor + Netty】响应式的、异步非阻塞的

参考

Spring WebFlux 入门
外行人都能看得懂的WebFlux,错过了血亏!
WebFlux 示例程序

代码

pom

    <!--基于Springboot-->
    <parent>
        <artifactId>spring-boot-starter-parent</artifactId>
        <groupId>org.springframework.boot</groupId>
        <version>2.3.1.RELEASE</version>
        <relativePath/>
    </parent>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <skipTests>true</skipTests>

        <spring-boot.version>2.3.1.RELEASE</spring-boot.version>
    </properties>
    <dependencies>
<!--        异步非阻塞并不会使程序运行得更快。WebFlux 并不能使接口的响应时间缩短,它仅仅能够提升吞吐量和伸缩性。-->
<!--        Spring WebFlux 是一个异步非阻塞的 Web 框架,所以,它特别适合应用在 IO 密集型的服务中,比如微服务网关这样的应用中。-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
    </dependencies>

yml

server:
  port: 8998
logging:
  file:
    path: ./logs
    name: spring-logs-demo.log

业务测试代码

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;
@Component
public class BusService {
    private static final Logger log = LoggerFactory.getLogger(BusService.class);
    public String implement(String type){
        log.info("执行耗时业务,{}",type);
        try {
            TimeUnit.SECONDS.sleep(2L);
        } catch (InterruptedException e) {
            log.info("睡眠异常");
        }
        return "hello.";
    }
}

接口-注解方式

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.stream.IntStream;

@RestController
@RequestMapping("/root")
public class RootController {
    private static final Logger log = LoggerFactory.getLogger(RootController.class);
    private BusService busService;
    @Autowired
    public void setBusService(BusService busService) {
        this.busService = busService;
    }

    @GetMapping("{id}")
    public Mono<String> hello(@PathVariable String id){
        log.info("spring-webflux 接口(方式1)-注解-start,id:{}",id);
        Mono<String> result = Mono.fromSupplier(()-> busService.implement("api1"));
        log.info("spring-webflux 接口(方式1)-注解-end");
        return result;
    }
    @GetMapping(value = "flux",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> flux(){
        log.info("spring-webflux 接口(方式1)-服务器推送");
        return Flux.fromStream(IntStream.range(1,5).mapToObj(i-> busService.implement("flux") + i));
    }
}

接口-路由方式

接口

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

@Component
public class RootHandler {
    private static final Logger log = LoggerFactory.getLogger(RootHandler.class);
    public Mono<ServerResponse> hello(ServerRequest request){
        String id = request.pathVariable("id");
        log.info("spring-webflux 接口(方式2)-声明式-start,id:{}",id);
        Mono<ServerResponse> mono = ServerResponse.ok().contentType(MediaType.TEXT_PLAIN)
                .body(BodyInserters.fromValue("Hello."));
        log.info("spring-webflux 接口(方式2)-声明式-end");
        return mono;
    }
}

路由配置

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;

@Configuration
public class RootRouter {
    private static final Logger log = LoggerFactory.getLogger(RootRouter.class);
    @Bean
    public RouterFunction<ServerResponse> router(RootHandler handler){
        log.info("spring-webflux 接口(方式2)-声明式-注入接口,{}",handler.getClass());
        return RouterFunctions.route(RequestPredicates.GET("/handler/hello/{id}")
                .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),handler::hello);
    }
}

测试

import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

public class RootWebClient {
    private final WebClient client = WebClient.create("http://localhost:8998");
    private final Mono<ClientResponse> result = client.get()
            .uri("/handler/hello/66")
            .accept(MediaType.TEXT_PLAIN).exchange();
    public String res(){
        return result.flatMap( r -> r.bodyToMono(String.class)).block();
    }
}

启动类

import cn.demo.flux.action.RootWebClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class WebFluxDemoApplication {
    private static final Logger log = LoggerFactory.getLogger(WebFluxDemoApplication.class);
    public static void main(String[] args) {
        log.info("start--->");
        SpringApplication.run(WebFluxDemoApplication.class,args);
        log.info("end--->");
        String res = new RootWebClient().res();
        log.info("send--->,{}",res);

    }
}

测试

代码测试

在这里插入图片描述

请求测试-1

在这里插入图片描述
在这里插入图片描述

请求测试2

在这里插入图片描述
在这里插入图片描述

测试推送

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

SpringBoot 集成 WebFlux,请求大模型实现 “打字机” 流式响应效果 WebFlux官方文档。 阅读详情

相关推荐

Spring Boot Webflux 实战演示:构建高并发Web应用

Spring Boot Webflux是Spring家族中的一个相对较新的成员,它代表了Spring在反应式编程领域的探索和应用。WebFlux是Spring 5的产物,是Spring Web的反应式编程API。它允许开发者构建异步的、非阻塞的网络应用,尤其适合运行在I/O密集型环境下,如微服务架构中的边缘服务或网关服务。反应式编程是一种编程范式,其核心思想是通过数据流和变化传递来实现异步数据处理。这种方式下,程序的控制流是通过异步数据流来驱动的。反应式编程模型主要用来处理高并发的数据场景。

weixin_35732273的博客 1068

SpringWebflux的简单Demo

webflux 简单demo

ZULJ131的博客 1408

springwebflux的demo

该项目是springwebflux的一个联系项目,仅用作入门webflux

SpringBoot之WebFlux的简单基本demo

当前springboot版本:2.1.18.RELEASE 1.声明 当前内容主要用于本人学习和使用Spring Boot WebFlux这个东西,基本来源SpringBoot官方文档 2.基本的pom依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version

编程学习者的博客 1279

springboot webflux demo

springboot 2.0 webflux 示例: https://blog.youkuaiyun.com/qq_28423433/article/details/81221933

Stata: 空间面板数据模型及Stata实现

  作者:游万海 (福州大学) Stata 连享会: 知乎 | 简书 | 码云 | 优快云   来源:Golgher 和 Voss (2016)   1. 背景介绍 由于面板数据模型所具有的众多优点 (刻画个体异质性,减弱模型共线性和增加自由度等),其被广泛应用于实证计量中。在 「 Stata: 面板数据模型-一文读懂」 文中,我们已对面板数据模型进行了介绍。 然而,当研究样本涉及到多个...

Stata连享会 7万+

Spring Boot集成webflux快速入门Demo

Spring WebFlux是一个异步非阻塞式的WEB框架,它能够充分利用多核CPU的硬件资源去处理大量的并发请求,而Spring MVC是构建于Servlet API之上,使用的是同步阻塞式I/O模型,即每一个请求对应一个线程去处理。

weixin_36873225的博客 1771

基于STM32的家用新风系统智能控制器 | 保姆式教程 开源可复刻

本项目基于STM32F103C8T6核心控制器,完整实现了家用新风系统智能控制器的全功能开发,覆盖多传感器数据采集、双模式控制、PID调速、异常报警、掉电记忆等核心功能,全程采用保姆式无跳步教学,从硬件选型、接线、CubeMX配置、代码开发、调试排坑全流程拆解,跟着步骤一步步操作,就能顺利完成项目复刻

ZhongWeiXiang9的博客 462

SpringBoot 2.0 Webflux 介绍 和Demo示例

 Spring WebFlux  1.1 WebFlux 简介 Spring WebFlux是Spring Framework 5.0中引入的新的反应式Web框架。与Spring MVC不同,它不需要Servlet API,完全异步且无阻塞,并 通过Reactor项目实现Reactive Streams规范。 Spring WebFlux有两种版本:基于功能和注释。基于注释的注释非常接近S...

carlos 程序员里最丑的 2万+

c语言实现求一个矩阵特征值和特征向量

前言 求矩阵的特征值,主要是用的QR分解,在我的有一次博客里,我已经详细地给出了计算的过程,大家有兴趣可以去看下,经过几天的钻研,终于完成了整个的eig算法。下面我将把我的整个代码附上,有不懂的可以问我,欢迎一起讨论学习! 这是对上一次的修改版,上一次写的程序是在C++编译环境下编译的,所以放在c里面编译有些会出错。 最后,如果有不对的地方希望大...

qq_36417014的博客 2万+

RK3588开发笔记-Buildroot编译host-nodejs报错解决ModuleNotFoundError: No module named ‘_bz2‘

在RK3588的开发过程中,使用Buildroot进行系统的构建和编译是一个常见的选择。然而,在编译host-nodejs的过程中,有时会遇到报错信息提示。这个错误通常是由于Python环境中缺少相应的模块导致的。以下将记录我解决这个问题的过程。。在RK3588的开发过程中,使用Buildroot编译host-nodejs时遇到的错误,通常是由于缺少相应的Python模块导致的。通过配置buildroot pythong bzip2开发库并重新编译,可以解决这个问题。

flypig has a dream! 898

springboot(六)——springboot与webflux结合初探

spring-cloud-gateway 的ReactorHttpHandlerAdapter 这几天看了看spring-cloud-gateway的请求处理流程,因为之前一直用的springboot1.x和spring4,一开始对spring-cloud-gateway的处理流程有点懵逼,找不到入口,后来跟了代码,在网上找了点资料,发现spring-cloud-gateway的入口在Reacto...

weixin_43087333的博客 694

医疗影像配准与融合: 使用MATLAB对医学影像进行配准和融合,实现不同影像模态之间的对准和结构信息融合等

医疗影像配准与融合是医学影像处理的重要技术,它用于将不同来源、不同时间或不同模态的医学影像进行配准和融合,以获得更加完整、准确的患者解剖信息。基于MATLAB的医疗影像配准与融合可以帮助医生更准确地诊断疾病,制定更有效的治疗方案。医疗影像配准与融合是医学影像处理的关键技术,它对于提高医学影像诊断和治疗的准确性至关重要。MATLAB是一种功能强大的数学和科学计算软件,它可以为医疗影像配准与融合提供强大的工具和支持。

走向CTO的路上... 709

Webflux。持续更新。。。

文章目录概念DEMO函数式 概念 webflux非阻塞,反应式函数编程。 DEMO 函数式 路由配置 @Configuration public class FlowRouteCfg { private static String PREFIX = "/api"; @Autowired FlowHandler flowHandler; @Bean publi...

般若 698

2021.02.23丨Virsorter2安装使用及答疑

最近项目比较多,又在学英语,写文章的时间少了很多。最近接到一个病毒组装的项目。用之前组装工具(ABYSS、SPAdes)都没有能够组装较为完整的scafford,今天介绍一款专门用于组装病毒的工具——Virsorter。 Virsorter最早版本发布于2015年,目前已经有了第二个版本。主要用于病毒的组装的注释。详细情况可以查看文章:https://peerj.com/articles/985/ 安装流程 安装文档: https://github.com/jiarong/VirSorter2/b

4835

GEE:本地影像上传到GEE的Assets中,并输入机器学习算法中作为特征变量

当我们在 Google Earth Engine(GEE)中应用机器学习算法时,会输入一些影像作为特征变量数据,进一步根据这些特征影像去推理未知区域的数据。但是 GEE 平台上计算特征变量的 API 函数并不是非常全面,我们希望获得更多的特征用于分类。这个时候,我们可以将本地计算的特征影像上传到 GEE 中进行后续处理。本文记录了从本地上传特征数据到 GEE 的 Assets 中的教程,用于后续在 GEE 中分类或者回归使用。本文也可作为《》一文的补充。

养乐多的博客 1729

SpringBoot 整合WebFlux

webflux 异步框架

u014365523的博客 7432

(二)使用VS2022克隆下载C++自制植物大战僵尸游戏教程

本文将介绍如何使用VS2022克隆下载《植物大战僵尸C++自制版本》。Gitee项目地址:Gitee仓库地址Github项目地址:Github仓库地址游戏官网地址(下载可直接运行)游戏官网。

尔灵尔亿的博客 4927

使用SpringWebFlux的反应式Web应用程序

1.反应式编程简介 反应式编程是为具有以下特征的应用程序创造的术语: 非阻塞应用 事件驱动和异步 需要少量线程来垂直扩展(即在JVM中) 就像面向对象的编程,函数式编程或过程式编程一样,反应式编程只是另一种编程范例。 它使我们的程序成为:响应式,弹性,弹性。 2. Spring的反应式编程 Spring框架内部使用Reactor为其自身提供响应式支持。 Reactor...

最佳 Java 编程 472

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Spring WebFlux零基础入门:从理论到Hello World

这个平台最让我惊喜的是,不需要配置任何环境,点击"运行"就能看到响应式编程的实际效果,还能一键部署自己修改后的版本。特别是他们的可视化数据流展示,把抽象的响应式概念变成了看得见的动画,对新手理解帮助很大。用Postman测试时,你会发现即使让接口休眠5秒,服务器仍然能处理其他请求——这就是非阻塞的魔力。用简单的HTML页面通过fetch API与后端交互,注意观察浏览器控制台的网络请求,你会发现数据是像水流一样逐步到达的,而不是一次性完整返回。WebFlux不是银弹,但确实是解决特定问题的利器。

SilvermistFalcon19的博客 452

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Spring Boot集成OpenAI API:从配置到生产部署的完整实践指南

在当今的软件开发中,API集成是连接不同服务与功能的核心技术。其原理是通过定义良好的接口规范,实现系统间的数据交换与功能调用。这项技术的价值在于能够快速引入外部能力,提升应用智能化水平,广泛应用于聊天机器人、内容生成等场景。在实际工程实践中,API密钥安全管理和Token计费机制是两个关键挑战。本文以OpenAI Completions API为例,详细讲解如何在Spring Boot项目中构建健壮的AI集成模块,涵盖环境配置、错误处理、性能优化等全流程,为开发者提供可落地的工程解决方案。

weixin_34026276的博客 508

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

实战基于Spring Boot 2的WebFlux和mLab搭建反应式Web

Spring Framework 5带来了新的Reactive Stack非阻塞式Web框架:Spring WebFlux。作为与Spring MVC并行使用的Web框架,Spring WebFlux依赖了反应式流适配器(Reactive Streams Adapter),在Netty和Servlet3.1的容器下,可以提供非阻塞式的Web服务,充分发挥...

weixin_34268753的博客 292

与Spring Webflux和新的CosmosDB API v3完全反应

Going full reactive? Following this blog post on Spring Boot and MongoDB, I decided to port it in order to be "fully reactive" : Migrating from the standard Spring Web stack to S...

专业的开发者“讨论” 402
上一篇: centos-7-安装minio-20220620
下一篇: centos 7安装podman(类似docker)
privateobject
博客等级 码龄9年 107粉丝 86原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值