新書推薦:
《
宋代冠服图志(详尽展示宋代各类冠服 精美插图 考据严谨 细节丰富)
》
售價:HK$
87.4
《
形似神异:什么是中日传统政治文化的结构性差异
》
售價:HK$
55.8
《
养育不好惹的小孩
》
售價:HK$
77.3
《
加加美高浩的手部绘画技法 II
》
售價:HK$
89.4
《
卡特里娜(“同一颗星球”丛书)
》
售價:HK$
87.4
《
伟大民族:从路易十五到拿破仑的法国史(方尖碑)
》
售價:HK$
188.2
《
古今“书画同源”论辨——中国书法与中国绘画的关系问题兼中国画笔墨研究
》
售價:HK$
132.2
《
《日本文学史序说》讲演录
》
售價:HK$
72.8
|
編輯推薦: |
1. 本书是作者知秋实践经验的总结,业内专家小马哥、梁桂钊、尹相宇、朱勇铭、芋艿、泥瓦匠等倾情力荐。
2. 知秋是国内为数不多的响应式和NIO方向的专家,本书是讲解响应式技术的书籍,在进行源码导读的同时,也引导读者对代码设计进行思考。
3. 响应式是未来的编程趋势,本书深入解读响应式RxJava 2的源码,从设计到实现细节,帮助读者达到RxJava 2源码库组件级别的拓展。
4. 本书包含大量案例,案例按照功能迭代的方式进行讲解,另外作者还录制了相关视频,可以配合学习。
|
內容簡介: |
本书主要讲解了到底什么是响应式,从代码设计层面将JDK 9+中的Flow API、RxJava 2中关于源的创建,以及调度与背压等相关核心操作娓娓道来,并通过实战案例帮助大家更好地理解和使用相关的API。本书涉及了大量并发编程方面的技巧,以及从基础代码角度介绍了各种接口、设计模式和与之相关的基础知识点,并将它们融会贯通。这就好比我们上学的时候,老师向我们传授基础知识,然后通过习题让我们掌握这些基础知识的运用技巧。本书也遵循了这个思路,同时这也符合我写书的初衷。
|
關於作者: |
知秋,本名李飞,长期致力于基础代码库的研发工作,通过博客与视频平台Bilibili,结合自己在基础库的研发经验做了大量源码解读分享。本人对JDK、Spring、RxJava、Spring Reactor、Netty、Reactor-Netty有很深刻的研究和独到的见解,并以此来打造Java编程方法论系列书籍。基于开源精神,与志同道合的伙伴一起创建了simviso开源分享团队,为开源社区服务。
|
目錄:
|
第1章响应式编程总览(Reactive Programming)1
1.1异步编程模式1
1.1.1并发2
1.1.2并行开发初探3
1.2流(Stream)3
1.3响应式流(Reactive Stream)4
1.3.1响应式流的特性4
1.3.2响应式开发的设计原则5
1.3.3响应式开发的好处6
1.4响应式开发工具库6
1.4.1RxJava简介6
1.4.2Reactor简介7
1.4.3MongoDB简介8
1.4.4响应式项目用例8
1.5Java 9中的响应式编程10
1.5.1响应式编程接口10
1.5.2Java 9响应式编程入门Demo12
1.5.3SubmissionPublisher类的源码解读18
1.5.4响应式编程整合Spring实战案例23
1.6小结29
第2章在RxJava中创建Observable30
2.1响应式编程所涉及的设计模式30
2.1.1观察者模式30
2.1.2迭代器模式30
2.2解读reactivex.Observable31
2.2.1从Flow.Publisher到Observable33
2.2.2subscribe的二三事33
2.2.3create方法的设计思想36
2.2.4各式各样的Observable40
2.2.5Observable.cache43
2.2.6无限流49
2.2.7在Observable内处理错误54
2.2.8定时控制Observable发送数据56
2.2.9Disposable延伸59
2.2.10ConnectableObservable解读67
2.2.11Observable中的publish.refCount解读76
2.2.12RxJava中的Subject解读79
2.3小结89
第3章RxJava 2中的操作90
3.1核心操作90
3.1.1使用filter进行条件过滤90
3.1.2使用map进行元素转换96
3.1.3使用flatMap进行扁平化转换98
3.1.4使用scan累加器112
3.1.5使用groupBy进行分组114
3.2多个Observable的合并操作122
3.2.1使用merge对Observable进行合并122
3.2.2使用zip方法进行合并124
3.2.3combineLatest操作135
3.2.4withLatestFrom操作141
3.2.5amb操作142
3.3高级操作143
3.3.1再谈累加器scan143
3.3.2聚合操作reduce144
3.3.3收集操作collect146
3.3.4使用distinct去重148
3.3.5使用distinctUntilChanged过滤重复数据152
3.3.6其他操作152
3.3.7自定义操作153
3.4小结159
第4章对RxJava 2的设计探索160
4.1源的创建设计思路160
4.2中间操作的转承162
4.3小结166
第5章Observable实战167
5.1初版架子实现167
5.1.1DAO层面的处理工作167
5.1.2控制层的响应式实现172
5.2基于架子实现一个汇率查询的服务175
5.3rxjava-web-spring-boot-starter的抽取设计179
5.4ObservableSseEmitter的设计实现188
5.5小结196
第6章RxJava 2中的多线程操作197
6.1初探RxJava并发编程197
6.2subscribeOn操作211
6.3observeOn操作216
6.4unsubscribeOn操作220
6.5调度器Scheduler226
6.5.1Schedulers.newThread方式227
6.5.2Schedulers.io方式227
6.5.3Schedulers.computation方式228
6.5.4Schedulers.fromExecutor executor自定义方式228
6.6小结230
第7章Flowable与背压231
7.1回顾背压231
7.2引入Flowable233
7.3探索Flowable.create234
7.3.1BackpressureStrategy.BUFFER策略239
7.3.2BackpressureStrategy.LATEST策略246
7.3.3BackpressureStrategy.DROP策略249
7.4将一个Observable转化为一个Flowable251
7.5通过onBackpressureXXX操作来实现背压策略252
7.5.1onBackPressureBuffer操作255
7.5.2onBackpressureLatest与onBackpressureDrop操作256
7.6Flowable.generate操作257
7.7小结262
第8章Flowable实战263
8.1使用Flowable封装JDBC263
8.1.1封装部分查询逻辑263
8.1.2封装update逻辑265
8.2结合Spring Web应用使用Flowable268
8.2.1接口数据的获取269
8.2.2响应式服务的源设计271
8.3单元测试274
8.3.1使用Mock Service Server进行测试274
8.3.2使用@Mock来进行一些服务测试277
8.4controller层的实现逻辑改造279
8.5小结282
|
內容試閱:
|
前 言
本书是Java编程方法论系列丛书的第一本书,Java编程方法论系列丛书将我多年的代码经验通过讲述优秀的RxJava 2、Reactor 3、Reactor-Netty与Spring WebFlux等框架库的源码细节展现出来,目的是让大家可以学习一种读源码的方式。也就是说,看源码不仅要看懂它干了什么,而且更应该看相关源码的设计思路以及技巧。这就好比研读一篇好文章一样,要揣摩作者的行文方式。
与理解代码相比,我更愿意带给大家的是一种生活态度。Java的第一个身份是语言,语言是用于描述我们的思想和生活的,所以带着生活中的理念来读源码,你就会发现情况大为不同:各种编程技巧和实现思路通通摆在了你的眼前。本系列丛书就是从这个角度出发的,所以针对的读者是那些想要提高自己对于基础代码掌控能力的中高级程序员。
下面具体介绍一下本书内容。本书主要讲解了到底什么是响应式,从代码设计层面将JDK 9 中的Flow API、RxJava 2中关于源的创建,以及调度与背压等相关核心操作娓娓道来,并通过实战案例帮助大家更好地理解和使用相关的API。本书涉及了大量并发编程方面的技巧,以及从基础代码角度介绍了各种接口、设计模式和与之相关的基础知识点,并将它们融会贯通。这就好比我们上学的时候,老师向我们传授基础知识,然后通过习题让我们掌握这些基础知识的运用技巧。本书也遵循了这个思路,同时这也符合我写书的初衷。
限于篇幅,有些内容没能完全在书中呈现,为了降低图书的阅读理解难度,我专门录制了相关的分享视频,可以更直观地带领大家走进源码世界。视频可以说是图书的有益补充,欢迎大家观看、学习。另外,希望读者通过学习本书了解响应式编程如何带来程序性能的提升以及其正确的使用方式。在录制本系列丛书的另一本书《Java编程方法论:响应式Reactor 3、Reactor-Netty和Spring WebFlux》(后续出版)的相关视频时,使我感到很荣幸的是,视频得到了Spring官方的肯定,并在Spring官方推特和博客上进行了宣传、推广,这增加了我对本系列丛书的信心。
最后,感谢尹相宇同学,没有你听我啰啰唆唆地讲代码,我估计自己的这份激情难以维持,当然,这本书的顺利出版也离不开你的审阅。另外,需要感谢的还有付睿编辑,她帮助我修正了很多表达细节上的错误。最后,感谢我的家人对我的理解和默默付出。
知秋(李飞)
2019年2月15日
推荐序一
在Architecture and Design InfoQ Trends Report - January 2019 (2019年1月的InfoQ架构和设计趋势报告)中,响应式编程(Reactive Programming)和函数式编程(Functional Programming)编列在第一季度(Q1)的Early Adopter(早期采纳者)中。尽管这仅是一家之言,但是不少开发人员逐渐意识到响应式之风已然吹起。也许你的生产系统尚未出现响应式的身影,不过你可能听说过Spring WebFlux或Netflix Hystrix等开源框架。笔者曾请教过Pivotal(Spring母公司)的布道师Josh Long :Spring技术栈未来的重心是否要布局在响应式上?对方的答复是:没错,响应式是未来的趋势。同时,越来越多的开源项目开始签署响应式宣言(The Reactive Manifesto) 并喊出了Web Are Reactive的口号。
或许开源界的种种举动无法说服你向响应式的港湾中停靠,不过Java 9中Flow API 的引入,又给业界注入了一剂强心针。不难看出,无论是Java API,还是Java框架,均走向了响应式编程模型的道路,这并非一种巧合。
通常,人们谈到的响应式可与响应式编程画等号,以非阻塞(Non-Blocking)和异步(Asynchronous)的特性并述,以数据结构与操作相辅相成。响应式编程涉及函数式和并发两种编程模型,前者关注语法特性,后者强调执行效率。简言之,响应式编程的意图在于Less Code,More Efficient。除此之外,笔者认为响应式更大的价值在于统一Java并发编程模型,使得同步和异步的实现代码无异,同时做到Java编程风格与其他编程语言更好地融合,或许你已经发现Java与JavaScript在响应式方面并不存在本质区别。纵观Java在响应式编程上的发展,其特性更新真可谓步步为营、如履薄冰。尽管Java线程API Thread与Runnable已具备异步以及非阻塞的能力,然而其同步和异步编程的模式并不统一,并且理解Thread API的细节和管理线程生命周期的成本均由开发人员承受。虽然在Java 5引入J.U.C框架(Java并发框架)之后,ExecutorService的实现减轻了以上负担,但是开发人员仍须关注ExecutorService的实现细节。比如,怎样合理地设置线程池空间及阻塞队列又成为新挑战。为此,Java 7引入了ForkJoinPool API,不过此时的J.U.C框架与响应式理念仍存在距离,即使是线程安全的数据结构也并不具备并行计算的能力(如集合并行排序),同时操作集合的手段也相当贫乏,缺少类似MapReduce等的操作。不过这些困难只是暂时的,终究会被Java 8救赎。Stream API的出现不仅具备数据操作在串行和并行间自由切换的能力(如sequential及parallel方法),而且淡化了并发的特性(如sorted方法既可以进行传统排序,也可以进行并行排序)。相同的设计哲学也体现在Java响应式实现框架中,如本书中提及的RxJava API io.reactivex.Observable。统一编程模型只是流的设计目标之一,它结合Lambda语法特性,虽然提供了数量可观的操作方法,如flatMap方法等,但是无论对比RxJava,还是Reactor ,流操作方法却又相形见绌。值得一提的是,这些操作方法在响应式的术语中被称为操作符(Operator)。当然框架内建操作符的多与少,并非判断其是否为响应式实现的依据。其中的决定性因素在于数据必须来自发布端(生产者)的推送(Push),而非消费端的拉取(Pull)。显然,流属于消费端已就绪(Ready)的数据集合,并不存在其他数据推送源。不过JVM语言早期的响应式定义处于模糊地带,如RxJava API属于观察者模式(Observer Pattern) 的扩展,而非迭代器模式(Iterator Pattern) 的实现。而Reactor的实现则拥抱响应式流规范 ,该规范中消费端对于数据的操作是被动地处理,而非主动地索取。换言之,数据的到达存在着不确定性 。当推送的数据无法得到消费端的及时响应时,响应式框架必须提供背压(Back Pressure) 实现,确保消费端拥有拒绝的权力(cancel)。在此理论基础上,响应式流规范定义了一套抽象的API,作为Java 9中java.util.concurrent.Flow API的顶层设计。不过关于操作符的部分,该规范似乎不太关心,这也是RxJava和Reactor均称自身为响应式扩展框架的原因,同时两者在API级别提供了多种调度器(Scheduler) 实现,可适配不同并发场景。尽管响应式定义在不同的阵营之间存在差异,但援引本人在《Reactive Programming:一种技术,各自表述》 一文中的总结:
Reactive Programming作为观察者(Observer)模式的延伸,不同于传统的命令编程(Imperative Programming)同步拉取数据的方式,如迭代器模式(Iterator),而是采用数据发布者同步或异步地推送到数据流(Data Stream)的方案。当该数据流(Data Stream)的订阅者监听到变化传播时,立即做出响应动作。在实现层面上,响应式编程可结合函数式编程简化面向对象语言语法的臃肿性,屏蔽并发实现的复杂细节,提供数据流的有序操作,从而达到提升代码的可读性以及减少Bug出现的目的。同时,响应式编程结合背压(Back Pressure)的技术解决了发布端生成数据的速度高于订阅端消费数据的速度的问题。
不难看出,响应式是一门综合的编程艺术,在实现框架的加持下,相同的代码逻辑可实现同步与异步非阻塞功能,从而达到提升应用整体性能的目的。不过现实的情况或许没有那么理想,Spring官方文档在Web on Reactive Stack章节中提到,响应式和非阻塞通常并不会让应用运行得更快 :
Reactive and non-blocking generally do not make applications run faster.
为此,JHipster 给出了一份Spring 5 WebFlux性能测试报告 ,其中一条结论是响应式应用并没有表现出速度的提升(甚至其速度变得更慢):
No improvement in speed was observed with our reactive apps the Gatling results are even slightly worse.
数月后,看似相反的结论却在DZone 的一篇名为Raw Performance Numbers - Spring Boot 2 Webflux vs. Spring Boot 1 的文章中出现,测试结果是Spring Boot 2 WebFlux在高并发下的响应时间更平稳。实际上,这个测试结果有些关公战秦琼的味道,毕竟Spring Boot 2下的WebFlux和Spring Boot 1下的Servlet容器所使用的线程模型是不同的,并且Serv
|
|