易筋SpringBoot 2.1 | 第三十篇:SpringBoot Reactor响应式编程介绍

写作时间:2019-11-29
Spring Boot: 2.2.1 ,JDK: 1.8, IDE: IntelliJ IDEA

说明

在计算机中,响应式编程或反应式编程(Reactive Programming)是一种面向数据流和变化传播的编程范式。这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算机模型会自动将变化的值通过数据流进行传播。

例如,在命令式编程环境中, a:=b+c表示将表达式的结果赋给a,而之后改变bc的值不会影响a。但在响应式编程中,a的值会随着bc的更新而更新。

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

官方内容

官方地址

  1. 响应式编程核心Reactive Core
    Reactor是一个没有任何阻塞的平台,并提供高效的管理工具. Reactor直接与Java 功能性 API, 与任何过程状态直接交互。包括:完成状态Completable Future, 数据流Stream 和 过程Duration.
  2. 可扩展接口Typed [0|1|N] Sequences
    Reactor 提供了2个响应式API构成(增强了扩展性):
  • Flux [N] : 表示可以有多个请求(比如:request(1).request(2)...)
  • Mono [0|1] :表示返回结果可以没有,或者有一个
  1. 非阻塞Non Blocking IO
    兼容微服务架构Microservices Architecture, Reactor 提供了 反压式网络引擎(backpressure-ready network engines), 支持请求协议 HTTP (包括 Websockets), TCP 和 UDP.
    在这里插入图片描述
    在响应式编程的顺序流中,Publisher生产数据. 默认情况下,Publisher什么事情都不会发生,知道Subscriber已经注册到Publisher, 这表明数据会推送给Subscriber.
    在这里插入图片描述

代理回调跟响应式编程对比

传统方式的回调黑洞 例子

userService.getFavorites(userId, new Callback<List<String>>() {  // 1
  public void onSuccess(List<String> list) {  // 2
    if (list.isEmpty()) {  // 3
      suggestionService.getSuggestions(new Callback<List<Favorite>>() { 
        public void onSuccess(List<Favorite> list) {  // 4
          UiUtils.submitOnUiThread(() -> {  // 5
            list.stream()
                .limit(5)
                .forEach(uiList::show);  // 6
            });
        }

        public void onError(Throwable error) { // 7
          UiUtils.errorPopup(error);
        }
      });
    } else {
      list.stream() // 8
          .limit(5)
          .forEach(favId -> favoriteService.getDetails(favId,  // 9
            new Callback<Favorite>() {
              public void onSuccess(Favorite details) {
                UiUtils.submitOnUiThread(() -> uiList.show(details));
              }

              public void onError(Throwable error) {
                UiUtils.errorPopup(error);
              }
            }
          ));
    }
  }

  public void onError(Throwable error) {
    UiUtils.errorPopup(error);
  }
});

解析:

  1. 这里有两个回调服务Callback , 一个是处理成功,一个处理错误.
  2. 第一个服务处理favorite IDs列表.
  3. 如果列表为空, 会跳转到suggestionService.
  4. suggestionService 提供列表 List<Favorite> 给第二个回调.
  5. 因为要处理UI, 需要确保处理逻辑在UI 线程中处理.
  6. Java 8 数据流限制了列表容量,这里suggestions只处理了5条 , 并显示在UI.
  7. 在每个阶段, 处理异常情况.
    Back to the favorite ID level. If the service returned a full list, we need to go to the
  8. 如果favorite IDs 列表不为空, favoriteService 将获得数据,并限制数量一样为5个.
  9. 跟推荐回调一样,在UI线程处理UI内容.

响应式编程的例子

userService.getFavorites(userId) // 1
           .flatMap(favoriteService::getDetails) // 2
           .switchIfEmpty(suggestionService.getSuggestions())  // 3
           .take(5)  // 4
           .publishOn(UiUtils.uiThreadScheduler())  // 5
           .subscribe(uiList::show, UiUtils::errorPopup); // 6 

解析:

  1. 首先,开始于获取用户收藏,是一个数据流Flow.
  2. 异步处理,获取并组装用户收藏数据,也是一个数据流.
  3. 如果用户收藏数据流为空,则调用suggestionService.
  4. 只需要结果的前5条数据.
  5. 最后,在UI 线程显示结果数据.
  6. 响应订阅数据流,如果有数据再UI线程显示,如果有错误弹窗显示错误信息.

上面例子来自 3.2. Asynchronicity to the Rescue?

参考

https://projectreactor.io/

https://zh.wikipedia.org/wiki/%E5%93%8D%E5%BA%94%E5%BC%8F%E7%BC%96%E7%A8%8B

http://wiki.jikexueyuan.com/project/android-weekly/issue-145/introduction-to-RP.html

https://gist.github.com/staltz/868e7e9bc2a7b8c1f754

https://github.com/reactor/reactor-core

https://projectreactor.io/docs/core/release/reference/index.html

https://github.com/reactor/reactor-core/blob/master/docs/asciidoc/reactiveProgramming.adoc

https://blog.51cto.com/liukang/2090170

https://blog.51cto.com/liukang/2090183

http://springcloud.cn/view/366

发布了127 篇原创文章 · 获赞 12 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/zgpeace/article/details/103311708