引言

​ 响应式编程是一种面向数据流和变化传播的编程范式。使用它可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。我们可以使用声明的方式构建应用程序的能力,形成更加敏感和有弹性的应用,所以Spring 5在其核心框架中增加了反应系统,已经开始向声明式编程的范式转变。

响应式编程的优势

  • 提高了代码的可读性,因此开发人员只需要关注定义业务逻辑。

  • 在高并发环境中,可以自然的处理消息。

  • 可以控制生产者和消费者之间的流量,避免内存不足。

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

  • 可以有效的管理多个连接系统之间的通信。

应用场景

  • 大量的交易处理服务,如银行部门。

  • 大型在线购物应用程序的通知服务,如亚马逊。

  • 股票价格同时变动的股票交易业务。

Spring 5.0前瞻

作为Java中的首个响应式Web框架,Spring 5.0最大的亮点莫过于提供了完整的端到端响应式编程的支持。
如上图所示左侧是传统的基于Servlet的Spring Web MVC框架,右侧是spring 5.0新引入的基于Reactive Streams的Spring WebFlux框架,从上往下依次是:Router Functions,WebFlux,Reactive Streams三个新组件,其中:

  • Router Functions: 对标@Controller,@RequestMapping等标准的Spring MVC注解,提供一套函数式风格的API,用于创建Router,Handler和Filter。

  • WebFlux: 核心组件,协调上下游各个组件提供响应式编程支持。

  • Reactive Streams: 一种支持背压(Backpressure)的异步数据流处理标准,主流实现有RxJava和Reactor,Spring WebFlux默认集成的是Reactor。

示例代码

1.创建项目

spring响应式开发,需要结合spring boot来完成,所以使用idea创建springboot项目,选择Spring Initializr选项,jdk选择1.8以上。 选择下一步,设置groupId和artifactId。
选择下一步,选择web选项中的Reactive web选项,表明要创建响应式项目,注意Spring Boot的版本为2.0.2。选择下一步,设置项目的目录,点击finish创建项目。

2.设置服务端口

为了避免端口冲突,我们可以在项目的application.properties文件中配置服务端口。

server.port=9002

3.相关依赖包

打开项目的pom.xml文件,会发现以下几个依赖包

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
​
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>io.projectreactor</groupId>
        <artifactId>reactor-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

其中:

  • spring-boot-starter-webflux:webflux依赖包,是响应式开发的核心依赖包,其中包含了spring-boot-starter-reactor-netty 、spring 5 webflux 包,默认是通过netty启动的。

  • spring-boot-starter-test:springboot的单元测试工具库。

  • reactor-test:Spring 5提供的官方针对RP框架测试工具库。

小结

​ spring响应式开发需要结合spring boot来完成,同时需要引入spring-boot-starter-webflux和reactor-test两个依赖包来支持响应式开发。

4.使用webflux创建web应用

webflux的使用有两种方式,基于注解和函数式编程。这里使用函数式编程,具体操作如下:

4.1.创建实体类

public class Good {​
    private int id;
    private String name;
    private String price;
​
    public Good(int id,String name,String price){        this.id=id;
        this.name=name;
        this.price=price;
    }
​
    public int getId() {        return id;
    }
​
    public void setId(int id) {        this.id = id;
    }
​
    public String getName() {        return name;
    }
​
    public void setName(String name) {        this.name = name;
    }
​
    public String getPrice() {        return price;
    }
​
    public void setPrice(String price) {        this.price = price;
    }
​
    @Override
    public String toString() {        return "Good{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", price='" + price + '\'' +
                '}';
    }
}

分析: 实体类没有什么特殊的操作,原来怎么操作现在还是怎么操作。

4.2.创建GoodGenerator

@Configuration
public class GoodGenerator {​
    public Flux<Good> findGoods(){        List<Good> goods = new ArrayList<>();
        goods.add(new Good(1,"小米","2000"));
        goods.add(new Good(2,"华为","4000"));
        goods.add(new Good(3,"苹果","8000"));
        return Flux.fromIterable(goods);
    }
}

分析: 这里的方法返回的是Flux类型的数据,Flux是RP中最基础的数据类型之一,对应的是多值数据的返回操作,在RP中还有Mono数据类型,也是最基础的数据类型之一,对应单值数据的返回操作。

注意:这里的GoodGenerator类要加上@Configuration注解。

4.3.创建GoodHandler

@Component
@Configuration
public class GoodHandler {​
    private final Flux<Good> goods;
​
    public GoodHandler(GoodGenerator goodGenerator) {        this.goods = goodGenerator.findGoods();
    }
​
    public Mono<ServerResponse> hello(ServerRequest request) {​
        return ok().contentType(TEXT_PLAIN)
                .body(BodyInserters.fromObject("Hello Spring!"));
    }
​
    public Mono<ServerResponse> echo(ServerRequest request) {        return ok().contentType(APPLICATION_STREAM_JSON)
                .body(this.goods,Good.class);
    }
}

分析: Handler主要用来处理请求操作,并将Mono<ServerResponse>返回,Mono<ServerResponse>中会封装响应数据,响应数据如果是字符串可以使用:

ok().contentType(TEXT_PLAIN).body(BodyInserters.fromObject("Hello Spring!"));

操作,如果是集合数据可以使用:

ok().contentType(APPLICATION_STREAM_JSON).body(this.goods,Good.class)

操作。

4.4.创建GoodRouter

@Configuration
public class GoodRouter {    @Bean
    public RouterFunction<ServerResponse> route(GoodHandler goodHandler) {​
      return RouterFunctions
              .route(RequestPredicates.GET("/good")
                      .and(RequestPredicates.accept(MediaType.TEXT_PLAIN)),goodHandler::hello)
              .andRoute(RequestPredicates.GET("/goods")
                      .and(RequestPredicates.accept(MediaType.APPLICATION_STREAM_JSON)),goodHandler::echo);
    }
​
}

分析: GoodRouter主要用来设置请求路径和转化HTTP请求,可以使用route()方法和andRoute方法设置多个请求路径和转化操作。

小结

​ HTTP请求会由GoodRouter转发给对应的Handler,Handler处理请求,并返回Mono<ServerResponse>,这里的Router类似@RequestMapping,Handler类似Controller

4.4.运行测试

​ 实体类、GoodGenerator、GoodHandler、GoodRouter都已经创建完成了,我们可以运行项目打开浏览器进行测试.

浏览器输入http://localhost:9002/good,即可获取到"Hello Spring!"文本信息

浏览器输入http://localhost:9002/goods,即可获取到集合信息

到目前为止,一个简单的webflux示例已经完成。

4.5.单元测试

在项目中我们也可以使用使用一个Spring 5新引入的测试工具类,WebTestClient,专门用于测试RP应用,具体代码如下:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class Spring5demoApplicationTests {​
    @Autowired
    private WebTestClient webTestClient;
​
    @Test
    public void helloTest() {      String s=  webTestClient
                .get().uri("/good")
                .accept(MediaType.TEXT_PLAIN).exchange()
                .expectStatus().isOk().returnResult(String.class)
                .getResponseBody().blockFirst();
​
        System.out.println(s);
    }
​
    @Test
    public void findGoodsTest(){        webTestClient.get().uri("/goods")
                .accept(MediaType.APPLICATION_STREAM_JSON)
                .exchange().expectStatus().isOk()
                .expectHeader().contentType(MediaType.APPLICATION_STREAM_JSON)
                .returnResult(Good.class)
                .getResponseBody().collectList();
    }
}

创建WebTestClient实例时可以看到,编写RP应用的单元测试,同样也是数据不落地的流式风格

总结

​ 到此,spring 5.0的响应式编程就给大家介绍到这里,这里只是简单进行了一个响应式入门操作,但是也能够体现出响应式编程的特点。当然spring 5.0响应式编程也不是完美的,它在故障诊断、依赖库集成、数据存储以及Spring Security安全权限框架支持等方面还是有局限性的。​

Spring5.0响应式编程入门相关推荐

  1. Concurrency in C# Cookbook中文翻译 :1.3并发性概述:响应式编程入门(Rx)

    Introduction to Reactive Programming (Rx) 响应式编程入门(Rx) Reactive programming has a higher learning cur ...

  2. 【Spring Boot 2.0学习之旅-15】SpringBoot2.0响应式编程

    SpringBoot2.0响应式编程 一.SpringBoot2.0 响应式编程基础知识 Spring WebFlux官方文档 SpringBoot WebFlux文档 1.什么是Spring Web ...

  3. 响应式编程入门:实现电梯调度模拟器

    据说每个程序员等电梯的时候都思考过电梯的调度算法-所以怎么动手实现一个呢?虽然这个场景貌似有些复杂,但却非常适合使用响应式编程的范式来处理.下面我们会在 RxJS 和 Vue 的基础上,一步步实现出一 ...

  4. java reactor例子_ProjectReactor响应式编程入门例子

    pom.xml配置 io.projectreactor reactor-core 3.3.10.RELEASE 实例 package top.senseiliu; import org.reactiv ...

  5. SpringBoot2.0响应式编程系列(一)-导读

  6. Spring下Redis的响应式编程

    Spring5支持响应式编程方式,能大大提高系统的吞吐量,但是要想实现整个系统的响应式编程需要每个环节都要实现,今天就来讲讲Spring是如何实现Redis的响应编程的. Spring Data Re ...

  7. springboot异步注解_Spring Boot 2 :Spring Boot 中的响应式编程和 WebFlux 入门

    [小宅按]Spring 5.0 中发布了重量级组件 Webflux,拉起了响应式编程的规模使用序幕. WebFlux 使用的场景是异步非阻塞的,使用 Webflux 作为系统解决方案,在大多数场景下可 ...

  8. (转)Spring Boot 2 (十):Spring Boot 中的响应式编程和 WebFlux 入门

    http://www.ityouknow.com/springboot/2019/02/12/spring-boot-webflux.html Spring 5.0 中发布了重量级组件 Webflux ...

  9. 玩转Spring—Spring5新特性之Reactive响应式编程实战

    1 什么是响应式编程 一句话总结:响应式编程是一种编程范式,通用和专注于数据流和变化的,并且是异步的. 维基百科原文: In computing, reactive programming is an ...

  10. Kotlin Flow响应式编程,基础知识入门

    Kotlin在推出多年之后已经变得非常普及了.相信现在至少有80%的Android项目已经在使用Kotlin开发,或者有部分功能使用Kotlin开发. 关于Kotlin方面的知识,我其实分享的文章并不 ...

最新文章

  1. Element 2.6.0 发布,基于 Vue 2.0 的桌面端组件库
  2. 网络工程师计算机类吗,机房网络工程师 | 网络工程专业的你知道吗?
  3. 比尔盖茨NEJM发文:新冠肺炎是百年一遇的流行病!全世界应该如何应对?
  4. 速读《构建之法:现代软件工程》提问
  5. PMCAFF产品经理社区原创专栏,产品圈的干货看这儿就够了
  6. 就这几个简单页面APP,这混小子要我10W块?!大家评评理!
  7. 腾讯2014年实习生招聘笔试面试经历
  8. string 方法 java_java中常用的String方法
  9. maven怎么引入自定义(本地/第三方)jar图文教程
  10. 从TensorFlow到PyTorch:九大深度学习框架哪款最适合你?
  11. 架构学习----消息队列
  12. 在window10上安装miniconda
  13. 大数据大屏设计-PS拉框助手
  14. [乐意黎原创]云南省红河州泸西县各乡镇及村委会区划代码和城乡划分代码
  15. FLV格式的视频歌曲地址600首,复制地址可插入外链播放器专用
  16. 戴尔u盘安装linux系统,戴尔服务器操作系统安装 Centos 系统安装详解教程。
  17. ‘MSOCache’是什么文件?
  18. 安卓手机做电脑摄像头(USB连接1080P 60FPS低延迟非常稳定)
  19. matlab ols regress,计量经济学简单线性回归OLS的Matlab程序.pdf
  20. 一文了解互联网运营核心指标(产品、运营人员必知)

热门文章

  1. sketch-矢量绘图应用软件
  2. 贴吧趣味问题——一线连24点【编程穷举证明无解】
  3. MODBUS通讯协议内容讲解
  4. 机器学习 | 实战(一)Decision_tree_红酒数据集
  5. ICTCLAS 汉语词性标注
  6. python tensorflow 以图搜图_以图搜图系统工程实践
  7. ADC噪声全面分析 -01- ADC噪声的类型以及ADC特性
  8. access如何求平均单价_ACCESS中计算日均值
  9. 两台电脑之间实现串口通信
  10. 计算机毕业设计Java-ssm博雅楼自习室预约系统源码+系统+数据库+lw文档