广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Spring-webflux 响应式编程的实例详解
  • 231
分享到

Spring-webflux 响应式编程的实例详解

2024-04-02 19:04:59 231人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录1. 前言2. spring-WEBflux简介3. 什么是“响应式”4. Spring-webflux的响应式api5. Spring mvc 还是 W

1. 前言

Spring 提供了两个并行堆栈。一种是基于带有 Spring MVC 和 Spring Data 结构的 Servlet API。另一个是完全反应式堆栈,它利用了 Spring WebFlux 和 Spring Data 的反应式存储库。在这两种情况下,Spring Security 都提供了对两种堆栈的支持。

反应式宣言

2. Spring-webflux简介

Spring WebFlux 是在 5.0 版中添加的。它是完全无阻塞的,支持 Reactive Streams背压,并且可以在 Netty、Undertow 和 Servlet 3.1+ 容器服务器上运行。

Spring-webflux官网

3. 什么是“响应式”

所谓响应式,举个例子,当调用一个api获取数据时,无需阻塞等待数据返回,而是当有数据返回时会进行告知。可见响应式是非阻塞的,意味着调用方法后,CPU可以去做别的事情,当接收到数据响应时CPU再回来处理,这种方式提高了系统的吞吐量。

而响应式编程,其实是为这种异步非阻塞的流式编程制定的一套标准。流式编程已不陌生了,Java8提供的stream api就是这种风格。这套标准包括对运行环境(JVMjavascript)以及网络协议相关的规范。

和传统的阻塞式servlet容器不一样。响应式容器能进一步提高资源的利用率,避免线程长时间处于等待状态,能以较少的线程处理更多的请求,缺点是整个处理链路必须是异步的,是基于事件响应的,不能阻塞事件线程,不然服务器性能会急剧下降,当然spring webflux并不能完整的替代传统的阻塞式容器,可根据需求进行选型。

应用案例Geteway

所有微服务的请求都会通过网关,如果采用mvc 对于并发量有一定的瓶颈。

4. Spring-webflux的响应式API

Spring-webflux框架是基于Reactor这个开源项目开发的。Reactor框架是跟Spring紧密配合的。

里边提供了两种API类型,分别是MonoFlux

  • Mono表示0 或 1个元素,
  • Flux表示0 至 N个元素,

5. Spring MVC 还是 WebFlux?

这两个web框架分别代表着两种不同类型的编程流派,官方给出了一个图作为对比如下

建议考虑以下具体点:

  • 如果您有一个运行良好的 Spring MVC 应用程序,则无需更改。命令式编程是编写、理解和调试代码的最简单方法。您可以选择最多的库,因为从历史上看,大多数都是阻塞的
  • Spring WebFlux 提供与该领域中其他人相同的执行模型优势,并且还提供服务器选择(Netty、Tomcat、Jetty、Undertow 和 Servlet 3.1+ 容器)、编程模型(带注释的控制器和功能性 Web 端点)的选择,以及反应库(Reactor、RxJava 或其他)的选择。
  • 如果您对用于 Java 8 lambda 或 Kotlin 的轻量级、功能性 Web 框架感兴趣,您可以使用 Spring WebFlux 功能性 Web 端点。对于要求不那么复杂的小型应用程序或微服务来说,这也是一个不错的选择,它们可以从更高的透明度和控制中受益。
  • 在微服务架构中,您可以混合使用带有 Spring MVC 或 Spring WebFlux 控制器或带有 Spring WebFlux 功能端点的应用程序。在两个框架中都支持相同的基于注释的编程模型,可以更轻松地重用知识,同时为正确的工作选择正确的工具
  • 评估应用程序的一种简单方法是检查其依赖关系。如果您要使用阻塞持久性 API(JPA、JDBC)或网络 API,那么 Spring MVC 至少是常见架构的最佳选择。Reactor 和 RxJava 在单独的线程上执行阻塞调用在技术上是可行的,但您不会充分利用非阻塞 Web 堆栈。
  • 如果您有一个调用远程服务的 Spring MVC 应用程序,请尝试响应式WebClient. 您可以直接从 Spring MVC 控制器方法返回反应类型(Reactor、RxJava或其他)。每个呼叫的延迟或呼叫之间的相互依赖性越大,好处就越显着。Spring MVC 控制器也可以调用其他响应式组件。
  • 如果您有一个大型团队,请记住向非阻塞、函数式和声明式编程转变的陡峭学习曲线。在没有完全开关的情况下启动的一种实用方法是使用 reactive WebClient。除此之外,从小处着手并衡量收益。我们预计,对于广泛的应用,这种转变是不必要的。如果您不确定要寻找什么好处,请先了解非阻塞 I/O 的工作原理(例如,单线程 node.js 上的并发性)及其影响。

其次: webflux兼容大部分springMVC的注解,也可以像mvc那样创建controller处理请求。

区别:

  • WebFlux是完全异步非阻塞的,SpringMVC是同步阻塞的。
  • WebFlux采用异步响应式编程,SpringMVC采用命令式编程。
  • WebFlux由于完全异步,所有操作数据库的框架,以及数据库也都要求是支持异步的,所以目前不支持mybatis、不支持oracle数据库。

6. 并发模型

尽管webmvcwebflux都支持使用注解来定义一个Controller,但是其实现方式完全不同。

webmvc是一个Servlet应用,实现是阻塞式IO,其维护一个线程池来处理每一个用户请求,也就是当Servlet容器启动时,就会创建比如10个线程出来,因此系统吞吐量的瓶颈在于有限的连接数和阻塞的请求处理过程。

webflux可以基于netty这样的NIO网络框架,它只需要很少的几个工作线程(Event loop worker)就能够处理并响应请求。由于无需阻塞等待方法返回,CPU资源就得到了更好的利用。

webflux并不能让程序运行地更快;而是提高了并发处理请求的能力,即提高系统吞吐量

7. webflux使用

pom依赖:

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

定义对象:

public class Person {
    private Integer id;
    private Integer age;
    private String name;

    public Person(Integer id, Integer age, String name) {
        this.id = id;
        this.age = age;
        this.name = name;
    }

    public Person() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

然后定义PersonController,响应式风格中不再使用@RequestMapping声明地址映射,而是通过RouterFunctions.route().GET()方法:

@Configuration
public class PersonRouter {
    @Resource
    private PersonHandler personHandler;
    @Bean
    public RouterFunction<ServerResponse> personRoutes() {
        return RouterFunctions.route()
                .GET("/person/{id}", RequestPredicates.accept(MediaType.APPLICATION_JSON), personHandler::getPerson)
                .GET("/person", RequestPredicates.accept(MediaType.APPLICATION_jsON), personHandler::listPeople)
                .POST("/person", personHandler::createPerson)
                .build();
    }
}

PersonHandler中处理对应的Http请求,等同于MVC架构中的Service层

@Component
public class PersonHandler {

    @Resource
    private IPersonDao personDao;

    public Mono<ServerResponse> listPeople(ServerRequest request) {
        Flux<Person> people = personDao.getList();
        return ServerResponse.ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(people, Person.class);
    }

    public Mono<ServerResponse> createPerson(ServerRequest request) {
        return request.bodyToMono(Person.class)
                .flatMap(i -> personDao.savePerson(i))
                .flatMap(p -> ServerResponse.ok().bodyValue(p));
    }

    public Mono<ServerResponse> getPerson(ServerRequest request) {
        int personId = Integer.parseInt(request.pathVariable("id"));
        return personDao.getPerson(personId)
                .flatMap(person -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).bodyValue(person))
                .switchIfEmpty(ServerResponse.notFound().build());
    }
}

IPersonDao

public interface IPersonDao {

    
    Flux<Person> getList();

    
    Mono<Void> savePerson(Person person);

    
    Mono<Person> getPerson(Integer id);
}

PersonDao

@Component
public class PersonDao implements IPersonDao {

    private final List<Person> personList = new ArrayList<>();

    public PersonDao() {
        this.personList.add(new Person(1, 17, "张三"));
        this.personList.add(new Person(2, 18, "李四"));
    }

    @Override
    public Flux<Person> getList() {
        return Flux.fromIterable(personList);
    }

    @Override
    public Mono<Void> savePerson(Person person) {
        personList.add(person);
        System.out.println("personList.size = " + personList);
        return Mono.empty();
    }

    @Override
    public Mono<Person> getPerson(Integer id) {
        return Mono.justOrEmpty(personList.stream().filter(p -> p.getId().equals(id)).findFirst());
    }
}
@SpringBootApplication
@EnableWebFlux
public class SpringWebfluxSessionApplication implements WebFluxConfigurer {
    public static void main(String[] args) {
        SpringApplication.run(SpringWebfluxSessionApplication.class, args);
    }
}

8. 测试

通过启动日志可以证实Spring-webflux是默认使用Netty提供HTTP服务

GET请求:http://127.0.0.1:8080/person

POST请求:http://127.0.0.1:8080/person

boyd:

{
    "id": 9,
    "age": 17,
    "name": "张三"
}

控制台输出:

GET请求:http://127.0.0.1:8080/person/9

完整代码已上传 gitee Spring整合常用组件

到此这篇关于Spring-webflux 响应式编程的文章就介绍到这了,更多相关Spring webflux 响应式编程内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Spring-webflux 响应式编程的实例详解

本文链接: https://www.lsjlt.com/news/166851.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Spring-webflux 响应式编程的实例详解
    目录1. 前言2. Spring-webflux简介3. 什么是“响应式”4. Spring-webflux的响应式API5. Spring MVC 还是 W...
    99+
    2022-11-13
  • Spring零基础入门WebFlux响应式编程
    目录简介响应式编程Reactor信号操作符SpringWebflux执行流程和API注解实现SpringWebflux说明:基于atguigu学习笔记。 简介 Webflux是 Sp...
    99+
    2022-11-13
    Spring WebFlux Spring WebFlux响应式编程
  • Spring响应式编程实例分析
    今天小编给大家分享一下Spring响应式编程实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。1. 前言了解响应式编程,...
    99+
    2023-07-02
  • 关于springboot响应式编程整合webFlux的问题
    在servlet3.0标准之前,是每一个请求对应一个线程。如果此时一个线程出现了高延迟,就会产生阻塞问题,从而导致整个服务出现严重的性能情况,因为一旦要调用第三方接口,就有可能出现这...
    99+
    2022-11-13
  • 如何分析springboot响应式编程整合webFlux的问题
    这期内容当中小编将会给大家带来有关如何分析springboot响应式编程整合webFlux的问题,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。在servlet3.0标准之前,是每一个请求对应一个线程。如果...
    99+
    2023-06-29
  • Spring Boot数据响应问题实例详解
    目录前言1、响应Json数据:Jackson.jar+@ResponseBody2、原理解析3、内容协商3.1、概述3.2、postman分别测试返回json和xml3.3、开启浏览...
    99+
    2022-11-13
  • three.js响应式设计实例详解
    目录1-canvas 的响应式布局示例:三维插图2-自适应设备分辨率总结源码地址:github.com/buglas/thre… 1-canvas 的响应式布局 can...
    99+
    2022-11-13
  • vue2.0响应式编程实例分析
    本篇内容介绍了“vue2.0响应式编程实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! vue2....
    99+
    2022-10-19
  • Vue.js响应式编程实例分析
    这篇文章主要介绍了Vue.js响应式编程实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Vue.js响应式编程实例分析文章都会有所收获,下面我们一起来看看吧。响应式编程展示数据,对象例子:var ...
    99+
    2023-06-27
  • ASP 和 Spring 教程:如何实现响应式编程?
    在当今的软件开发领域中,响应式编程已经成为一种非常流行的编程范式。ASP 和 Spring 是两个非常流行的 Web 框架,本篇文章将介绍如何使用 ASP 和 Spring 实现响应式编程。 什么是响应式编程? 响应式编程是一种基于事件驱...
    99+
    2023-10-29
    响应 spring 教程
  • Vue响应式原理的示例详解
    Vue 最独特的特性之一,是非侵入式的响应系统。数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。聊到 Vue 响应式实现原理,众多开发者都知道实现...
    99+
    2022-11-13
  • vue3响应式对象的api超全实例详解
    目录Ⅰ. ref、reactive ( 递归监听 )Ⅱ. isRef、isReactive ( 判断 )Ⅲ. toRef 和 toRefs ( 解构 )Ⅳ. toRaw 、 mark...
    99+
    2023-05-19
    vue3响应式对象api vue中api vue 响应式
  • Spring响应式编程:Java API中的新趋势?
    随着现代化Web应用程序的不断发展,对于高吞吐量和低延迟的需求越来越高。在这样的需求下,异步编程和响应式编程成为了重要的解决方案。Spring框架一直以来都是Java开发中最受欢迎的框架之一,而现在,Spring框架也引入了响应式编程模型...
    99+
    2023-09-21
    api spring 响应
  • 如何在Java API中实现基于Spring的响应式编程?
    响应式编程是一种以数据流和变化传播为基础的编程模型,它通过异步编程来提高应用程序的响应能力和并发性。Spring框架从4.0版本开始引入了对响应式编程的支持,使得基于Spring的应用程序可以更好地应对高并发和高吞吐的场景。本文将介绍如何在...
    99+
    2023-09-21
    api spring 响应
  • 实例详解jQuery的链式编程风格
    链式编程的实现原理 jQuery可以让我们开发者一直使用点语法调用自身方法的原理,主要原因是jQuery内部利用了js的对象来实现。 在jQuery中,如果一直对同一个元素或元素的...
    99+
    2022-11-12
  • Spring实例化bean的四种方式详解
    目录一、bean实例化——构造方法(常用)二、bean实例化——静态工厂(了解)三、bean实例化——实例工厂...
    99+
    2022-11-13
  • Spring Bean获取方式的实例化方式详解
    目录1.通过构造方法实例化2.通过简单工厂模式实例化3.通过factory-bean实例化4.通过FactoryBean接口实例化5.BeanFactory和FactoryBean的...
    99+
    2023-03-09
    Spring获取bean的方式 Spring Bean获取方式
  • 响应式编程与Spring:如何提高Java应用程序的效率?
    随着用户对互联网的需求越来越高,高性能、高并发的 Java 应用程序越来越受到开发者的关注。而响应式编程是一种能够提高应用程序效率的编程范式。本文将介绍什么是响应式编程,为什么要使用它以及如何将其与 Spring 框架结合使用。 一、什么...
    99+
    2023-11-06
    响应 并发 spring
  • 详解vue3 响应式的实现原理
    目录核心设计思想Vue.js 2.x 响应式Vue.js 3.x 响应式依赖收集:get 函数派发通知:set 函数总结源码参考核心设计思想 除了组件化,Vue.js 另一个核心设计...
    99+
    2022-11-13
  • VUE响应式原理的实现详解
    目录总结前言 相信vue学习者都会发现,vue使用起来上手非常方便,例如双向绑定机制,让我们实现视图、数据层的快速同步,但双向绑定机制实现的核心数据响应的原理是怎么样的呢,接下来让我...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作