浅谈Spring5 响应式编程

近年来,响应式编程在开发者社区和客户中很受欢迎,由于其以声明的方式构建应用程序的能力,而不是强制,形成更加敏感和有弹性的应用。Spring 5 将反应系统纳入其核心框架的事实已经显示出向声明式编程的范式转变。

响应式编程管理数据生产者和消费者之间的异步数据流,它们需要以流畅的方式对数据进行响应。所以,响应式编程都是异步和事件驱动的流畅应用程序,需要少量的线程进行缩放。

响应式编程很难构建基于线程的架构,由于在基于共享可变状态、线程和锁的应用程序扩展过程中涉及到高度复杂性。

在响应式编程的上下文中,“在流中有数据时,所有事物都是流并以流畅方式行为。”

为什么是响应式编程

高层次的抽象与响应式编程导致了代码可读性的提高,因此开发人员可以主要关注定义业务逻辑的事件的相互依存性。

在高度并发的环境中,响应模式自然地适合于消息处理,这是一个常见的企业用例。

由于执行反压力的特性,响应式方法最适合控制生产者和消费者之间的流量,这将有助于避免内存不足。

对于一个或几个线程,IO绑定任务可以通过异步和非阻塞方式执行,而且不阻塞当前线程。

在高交互和实时应用程序或任何操作/事件时,都可能触发多个连接子系统的通知,在这种情况下响应式编程可以更有效的进行管理。

用于响应式编程实现的理想案例

  1. 大量的交易处理服务,如银行部门。
  2. 大型在线购物应用程序的通知服务,如亚马逊。
  3. 股票价格同时变动的股票交易业务。

响应流 (Reactive Streams)

“响应流”定义一个 API 规范,其中包含一组最小的接口,这些接口公开了定义非阻塞反压力的数据流的操作和实体的方法。

随着反压力的引入,响应流允许用户控制来自出版商的数据交换速率。

响应流 API java.util.concurrent.flow 已正式成为 java 9 的一部分。

响应流主要用作互操作层。

Spring 5 提供的响应式编程

Spring-Web-Reactive 模块和 Spring MVC 都支持相同的 @Controller 编程,但 Spring-Web-Reactive 是在 Reactive 和非阻塞引擎上执行的。

遵循这个文档,见:
http://docs.spring.io/spring-framework/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/web-reactive.html

Spring-Web-Reactive 模块和 Spring MVC 共享许多通用的算法,但 Spring-Web-Reactive 模块已经重新定义了许多 Spring MVC 契约,例如 HandlerMapping和HandlerAdapter,以使它们变得异步和非阻塞,以及启用响应式 HTTP 请求和响应(以 RouterFunction 和 HandlerFunction 的形式)。

除了现有的 RestTemplate 外,新的响应式 WebClient 也在 Spring 5 中引入。

支持响应式编程的 HTTP 客户端(例如 Reactor、Netty、Undertow)已经采用了一系列响应式的 ClientHttpRequest 和 ClientHttpResponse 抽象,它们将请求和响应体作为 Flux <DataBuffer> 公开,并且在读写端提供全面的背压支持。

Spring 5 Framework 引入了 Reactor,作为 Reactive Streams 规范的实现。

Reactor 是用于在 JVM 上构建非阻塞应用程序的下一代 Reactive 库。

Reactor 扩展了基本的 Reactive Streams Publisher 契约,并定义了 Flux 和 Mono API 类型,分别为 0..N 和 0..1 的数据序列提供声明性操作。

Spring Web Reactive 使用 Servlet 3.1 提供了非阻塞 I/O,并运行在 Servlet 3.1 容器上。

Spring WebFlux 提供了两种编程模型可供选择。

  1. 注解式控制器:这些与 Spring MVC 相同,在使用一些 Spring-Web 模块提供的附加注解的情况下。Spring MVC 和 WebFlux 控制器都支持 Reactive 返回类型。另外,WebFlux 还支持 Reactive @RequestBody 参数。
  2. 函数式编程模型:基于 lambda 的轻量级小型库,用于给出路由和处理请求的实用程序。

Spring Web Reactive vs. Spring Web MVC

Spring 5 包含了 Spring Web Reactive(在 spring-web-reactive 模块下)和 Spring Web MVC(在 spring-webmvc 模块下)。

虽然 Spring Web Reactive 和 Spring Web MVC 模块共享了很多算法,但是由于 Spring Web Reactive 能够在响应式的非阻塞 Reactive Streams HTTP 适配器层上运行,因此它们之间不共享代码。

Spring MVC 执行需要 Servlet 容器,而 Spring Web Reactive 也可以在非 Servlet 运行时上运行,比如在 Netty 和 Undertow 上运行。

如果对具有轻量级、函数式的 Web 框架的非阻塞 Web 栈的必要要求,并与 Java 8 lambda 或 Kotlin一起使用,则应该考虑从 Spring MVC 应用程序切换到 Spring Web Reactive。

响应式编程的基本结构

这是一个 2.0.0 M5 版本的  pom.xml ,依赖于 WebFiux。

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

传统方法 VS. 响应方法

在传统方法中,执行将被阻塞,并将一直等到您的服务执行完成为止。在下面的代码中,在第一个 print 语句之后,程序执行将被阻塞并等待服务执行完成。在服务执行完成后,将恢复程序执行,并执行第二个 print 语句。

@GetMapping("/traditional")
public List < Product > getAllProducts() {
 System.out.println("Traditional way started");
 List < Product > products = prodService.getProducts("traditional");
 System.out.println("Traditional way completed");
 return products;
}

在响应方法中,程序执行将继续,而不用等待服务执行的完成。在下面的代码中,在第一个 print 语句之后,第二个 print 语句将以非阻塞的方式执行,而无需等待服务执行的完成。Flux stream 将随着产品数据的可用性而被填充。

@GetMapping(value = "/reactive", .TEXT_EVENT_STREAM_VALUE)
public Flux < Product > getAll() {
 System.out.println("Reactive way using Flux started");
 Flux < Product > fluxProducts = prodService.getProductsStream("Flux");
 System.out.println("Reactive way using Flux completed");
 return fluxProducts;
}

Reactive Web Client

除了现有的 RestTemplate 之外,Spring 5 还引入了 Reactive WebClient。

ClientHttpRequest 和 ClientHttpResponse 抽象将请求和响应主体使用 Flux <DataBuffer> 公开,并在读和写端提供完全背压支持。

来自 Spring Core 的编码器和解码器抽象也用在客户端,用于将字节序的 Flus 序列化或发序列化成类型对象。

下面是一个 Reactive WebClient 的示例,它调用终端并接收及处理 Reactive Stream Flux 对象。

@GetMapping("/accounts/{id}/alerts")
public Flux < Alert > getAccountAlerts(@PathVariable Long id) {
 WebClient webClient = new WebClient(new ReactorClientHttpConnector());
 return this.repository.getAccount(id).flatMap(account -> webClient.perform(get("/alerts/{key}", account.getKey())).extract(bodyStream(Alert.class)));
}

Spring 5 的局限

  1. 对 Reactive 应用程序进行故障诊断有点困难,并且你有可能在解决问题的同时,意外地阻塞了已经引入的代码。
  2. 大多数传统的基于 Java 的集成库仍然是阻塞的。
  3. 可用于 Reactive 数据存储的选项是非常有限的,少数 NoSQL 数据库(如 MongoDB)除外。
  4. Spring Security 仍然不被支持。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 浅谈SpringBoot之开启数据库迁移的FlyWay使用

    本文介绍了SpringBoot开启数据库迁移的FlyWay使用,分享给大家,具体如下: 一,首先我先了解下FlyWay是如何运转的. 最简单的方案是将Flyway指向一个空数据库. 它将尝试找到其元数据表.当数据库为空时,Flyway将不会找到它, 而是创建它.您现在拥有一个名为SCHEMA_VERSION的单个空表的数据库 : 该表将用于跟踪数据库的状态.之后,Flyway将开始扫描应用程序的文件系统或类路径进行迁移.它们可以用Sql或Java编写. 然后根据其版本号对迁移进行排序,并按顺序应

  • jQuery+SpringMVC中的复选框选择与传值实例

    一.checkbox选择 在jQuery中,选中checkbox通用的两种方式: $("#cb1").attr("checked","checked"); $("#cb1").attr("checked",true); 对应的jQuery函数,主要完成三个功能: 1.第一个复选框选中或取消选中,则下面的复选框为全选或取消全选: 2.当下面的复选框全部选中时,则将第一个复选框设置为选中,当下面的复选框中有一个

  • Spring循环依赖正确性及Bean注入的顺序关系详解

    一.前言 我们知道 Spring 可以是懒加载的,就是当真正使用到 Bean 的时候才实例化 Bean.当然也不全是这样,例如配置 Bean 的 lazy-init 属性,可以控制 Spring 的加载时机.现在机器的性能.内存等都比较高,基本上也不使用懒加载,在容器启动时候来加载bean,启动时间稍微长一点儿,这样在实际获取 bean 供业务使用时,就可以减轻不少负担,这个后面再做分析. 我们使用到 Bean 的时候,最直接的方式就是从 Factroy 中获取,这个就是加载 Bean 实例的源

  • Intellij IDEA 2017新特性之Spring Boot相关特征介绍

    前言 Intellij IDEA 2017.2.2版本针对Springboot设置了一些特性,本篇文章给大家简单介绍一下如何使用这些特性. Run Dashboard 针对Spring boot提供了Run Dashboard方式的来代替传统的run方法.下面看一下官网提供的面板结构图: 是不是很炫,直接可以通过Dashboard看到Springboot的启动项目,并显示相应的端口等信息,同时还能在这里进行相应的操作.下面我们来看看如何调用出Dashboard. 首先,你的项目应该是一个spri

  • Spring的实例工厂方法和静态工厂方法实例代码

    Spring的实例工厂方法和静态工厂方法都可以用来实例化bean,本文我们就来看看相关实例. 静态工厂方法:直接调用静态方法可以返回Bean的实例 package com.zhu.string.factory; import java.util.HashMap; import java.util.Map; public class StaticCarFactory { /** * 静态工厂方法:直接调用静态方法可以返回Bean的实例 * */ private static Map<String

  • 浅谈SpringMVC中post checkbox 多选框value的值(隐藏域方式)

    我这里往后端传递checkbox 多选框value的值是通过字符串方式传递,先调用js对选定checkbox遍历获取选的的boxvalue,然后写进隐藏域,最后作文对象的属性提交.见代码:` 前端: <form:form commandName="user" method="post"> <c:forEach items="${deploys}" var="deploy" varStatus="de

  • Spring工厂方法创建(实例化)bean实例代码

    目标明确 简单叙述一下本文想要解决的问题:如何在Spring中不再使用Spring创建Bean实例,而是把Bean创建过程转移到开发者手中. 思路清晰 创建Bean实例的方式: 1) 通过构造器(有参或无参) 方式: <bean id="" class=""/> 2) 通过静态工厂方法 方式: <bean id="" class="工厂类" factory-method="静态工厂方法"/

  • 从SpringMVC迁移到Springboot的方法步骤

    在将SpringMVC项目转移到Springboot上的过程中,主要做了以下的事情 Profile配置 全局变量从properties文件读入 数据源与Mybatis配置 日志文件配置 WebConfig配置(包括原有的web.xml和spring-mvc.xml) 去掉多余的bean注入 本篇文章除了介绍做了些什么和怎么做之外,会多很多多余的废话,关于对原理的一些探讨,知其然也要知其所以然. Profile配置 在传统的Spring项目中,多个profile的配置方式首先是在pom.xml文件

  • 浅谈Spring5 响应式编程

    近年来,响应式编程在开发者社区和客户中很受欢迎,由于其以声明的方式构建应用程序的能力,而不是强制,形成更加敏感和有弹性的应用.Spring 5 将反应系统纳入其核心框架的事实已经显示出向声明式编程的范式转变. 响应式编程管理数据生产者和消费者之间的异步数据流,它们需要以流畅的方式对数据进行响应.所以,响应式编程都是异步和事件驱动的流畅应用程序,需要少量的线程进行缩放. 响应式编程很难构建基于线程的架构,由于在基于共享可变状态.线程和锁的应用程序扩展过程中涉及到高度复杂性. 在响应式编程的上下文中

  • 浅谈Rx响应式编程

    目录 一.Observable 二.高阶函数 三.快递盒模型 3.1.快递盒模型1:fromEvent 3.2.快递盒模型2:interval 四.高阶快递盒 五.销毁快递盒 5.1.销毁快递盒--取消订阅 5.2.销毁高阶快递盒 六.补充 七.后记 一.Observable Observable从字面翻译来说叫做"可观察者",换言之就是某种"数据源"或者"事件源",这种数据源具有可被观察的能力,这个和你主动去捞数据有本质区别.用一个形象的比喻就

  • 浅谈Java响应式系统

    初识响应式系统 ReactiveX的本质就是Observer+Iterator+函数编程+异步.是一个事件驱动的,异步的,可观察的序列. 使用RxJava可以将异步的回调改写成为链式调用.在代码上看起来非常简洁明了.当然JDK也提供了CompletionStage提供了类似的解决回调的功能. Rxjava只是一个java的基本库,如果我们想要构建响应式的服务器,响应式的web,响应式的数据访问,甚至是响应式的微服务,又该如何处理呢? 这个时候我了解到了Vert.x.Vert.x就是用来构建Rea

  • 浅谈Python响应式类库RxPy

    一.基本概念 Reactive X中有几个核心的概念,先来简单介绍一下. 1.1.Observable和Observer(可观察对象和观察者) 首先是Observable和Observer,它们分别是可观察对象和观察者.Observable可以理解为一个异步的数据源,会发送一系列的值.Observer则类似于消费者,需要先订阅Observable,然后才可以接收到其发射的值.可以说这组概念是设计模式中的观察者模式和生产者-消费者模式的综合体. 1.2.Operator(操作符) 另外一个非常重要

  • 浅谈Vue响应式(数组变异方法)

    前言 很多初使用Vue的同学会发现,在改变数组的值的时候,值确实是改变了,但是视图却无动于衷,果然是因为数组太高冷了吗? 查看官方文档才发现,不是女神太高冷,而是你没用对方法. 看来想让女神自己动,关键得用对方法.虽然在官方文档中已经给出了方法,但是在下实在好奇的紧,想要解锁更多姿势的话,那就必须先要深入女神的心,于是乎才有了去探索Vue响应式原理的想法.(如果你愿意一层一层地剥开我的心.你会发现,你会讶异-- 沉迷于鬼哭狼嚎 无法自拔QAQ). 前排提示,Vue的响应式原理主要是使用了ES5的

  • Spring5新特性之Reactive响应式编程

    目录 1什么是响应式编程 2回顾Reactor 2.1什么是Reactor 2.2为什么是Reactor 2.3Reactor模式的经典实现—Netty 3Spring5中多Reactive的支持 3.1SpringWebflux 3.1.1依赖 3.1.2Controller代码 3.1.3测试 3.1.4SpringMVC和SpringWebFlux模式上的不同 3.2SpringDataReactiveRespositories 3.2.1依赖 3.2.2配置 3.3.3测试 4如何理解R

  • 利用Swift实现一个响应式编程库

    前言 整个2017年我完全使用 Swift 进行开发了.使用 Swift 进行开发是一个很愉快的体验,我已经完全不想再去碰 OC 了.最近想做一个响应式编程的库,所以就把它拿来分享一下. 在缺乏好的资源的情况下,学习响应式编程成为痛苦.我开始学的时候,做死地找各种教程.结果发现有用的只是极少部分,而且这少部分也只是表面上的东西,对于整个体系结构的理解也起不了多大的作用. Reactive Programing 说到响应式编程,ReactiveCocoa 和 RxSwift 可以说是目前 iOS

  • 浅谈Java实现面向对象编程java oop

    一.对象的综述 面向对象编程(OOP)具有多方面的吸引力.对管理人员,它实现了更快和更廉价的开发与维护过程.对分析与设计人员,建模处理变得更加简单,能生成清晰.易于维护的设计方案.对程序员,对象模型显得如此高雅和浅显.此外,面向对象工具以及库的巨大威力使编程成为一项更使人愉悦的任务.每个人都可从中获益,至少表面如此. 所有编程语言的最终目的都是解决企业又或者人在现实生活中所遇到的问题,最初我们的程序可能长这样"11111100001",相信大家都不会陌生,只是大家没这么子去敲过代码.再

  • 浅谈Python的元编程

    目录 一.装饰器 二.装饰器的执行顺序 三.元类 四.descriptor 类(描述符类) 五.总结 相应的元编程就是描述代码本身的代码,元编程就是关于创建操作源代码(比如修改.生成或包装原来的代码)的函数和类.主要技术是使用装饰器.元类.描述符类. 一.装饰器 装饰器就是函数的函数,它接受一个函数作为参数并返回一个新的函数,在不改变原来函数代码的情况下为其增加新的功能,比如最常用的计时装饰器: from functools import wraps def timeit(logger=None

  • 关于springboot响应式编程整合webFlux的问题

    在servlet3.0标准之前,是每一个请求对应一个线程.如果此时一个线程出现了高延迟,就会产生阻塞问题,从而导致整个服务出现严重的性能情况,因为一旦要调用第三方接口,就有可能出现这样的操作了.早期的处理方式只能是手工控制线程. 在servlet3.0标准之后,为了解决此类问题,所以提供了异步响应的支持.在异步响应处理结构中,可以将耗时操作的部分交由一个专属的异步线程进行响应处理,同时请求的线程资源将被释放,并将该线程返回到线程池中,以供其他用户使用,这样的操作机制将极大的提升程序的并发性能.

随机推荐