Spring Leader分享:Spring Framework之再探Core Container 下

特别说明

这是一个由simviso团队进行的关于Spring Framework 5.2版本内容分享的视频翻译文档,分享者是Spring Framework 5.2项目leader。方便你们在将来某个时候回顾的时候能够快速定位内容。java

视频地址:web

【国外前沿技术分享-后端-中文字幕】Spring Framework之再探Core Container 上数据库

【国外前沿技术分享-后端-中文字幕】Spring Framework之再探Core Container 中编程

【国外前沿技术分享-后端-中文字幕】Spring Framework之再探Core Container 下后端

视频翻译文字版权归 simviso全部,未经受权,请勿转载架构

参与人员名单:

1. 响应式在Spring中的应用

Ok,虽然放在最后但依然比较重要,让咱们接着讨论响应式的话题。今天响应式的话题主要是围绕你们所知的Spring WebFlux。咱们在Spring Framework 5.2 中引入了响应式Endpoints(请求路径)的Web Controller模型,这里跟老一套Controller的典型结构很像。app

这里的@GetMapping注解声明了HTTP Endpoints(请求路径),以及响应式的返回值(Mono)。在这个特定的例子中,响应式的返回值是Reactor Mono和Reactor Flux类型。同时,返回类型也能够是Reactive Stream Publisher的任意一种实现,只不过这里的Mono和Flux是Reactor Project下的对Publisher的一种特殊实现。你也能够返回RxJava下的Flowable和Single类型,不管你选择哪一种,咱们都须要知道该对它们进行怎样的处理。咱们在运行时将它们集成到咱们的Reactive Pipeline中。经过Reactor Core这个项目来对这个过程进行Reactive适配实现,咱们在Spring 5.0中就已经引入了Reactor Core。在接下来的时间里,我将阐述一些细节以及更深刻的东西。异步

这些返回响应式返回值的方法,在Spring MVC中一样可用。Spring WebFlux 是咱们响应式Web栈,在Netty上面运行的EventLoop和Web栈是彻底分离的。但若是咱们讨论的是Spring MVC的话,它是一个基于Servlet的Web栈。你一样能够响应式的方式返回数据,便可以在这里返回Reactive Stream Publisher。它们虽然具备一样的组件模型,可是它们运行时的处理策略是不同的。咱们基本上是将Servlet请求切换到它的异步模式,咱们对Servlet的异步流处理适配了一套Reactive Stream Publisher实现,这里甚至使用了一点背压。socket

隐藏在它们背后的是不同的架构处理,可是它们表达了一个相似的意图,相似的目的。咱们正尽最大的努力来让Reactive Stream Publisher能够应用在Spring MVC Servlet 架构上面。你能够很好的基于一些需求来进行工做 而这些需求不须要你进行彻底的背压或彻底的基于EventLoop的处理(Netty中的EventLoop处理)。它是基于一个DeferredResult来替代实现。ide

Spring MVC距离拥有这样功能的一个DeferredResult还有很长时间,这个就像拥有对Reactive Stream Publisher这样的返回值类型进行处理能力的DeferredResult。若是你在WebFlux上进行同种类型的请求处理,它们实际上经过基于EventLoop的架构全程进行响应式处理。今后处能够看出,在WebFlux上对于请求路径的处理(Endpoints)是有点不同的。在Spring MVC中你能够将常规标准的阻塞式同步Endpoints(图中路径对应的处理方法)与Reactive Streams Publisher这种返回类型混合使用。想要作到这点真的还有很长的路要走。

2. 响应式事务处理

和刚才所讲的这些事情同样,大部分的Spring功能均可以经过一些有趣的途径将它们整合到一块儿。对于响应式功能来说,一样如此。一个很明显的例子就是Spring Framework 5.2中的响应式事务处理。咱们拿图中这个Service class中的@Transactional方法来说。在方法上声明@Transactional注解,同时返回一个Reactive Streams Publisher。当咱们进行事务拦截的时候会说,这不是一个常规的事务方法常规的事务方法是在同一个线程上咱们在调用方法时开启事务,在方法返回的时候对事务进行 commit 或 rollback。

这是一个不同的method,它须要经过一个指令级流式编程的风格返回一个Reactive Streams Publisher。你每每须要在里面经过一系列方法创建管道式的链式调用。在这里,它调用了一个Repositiory的指令,多是一个Spring Data Repositiory,也多是自定义的,这里并无什么区别。它调用一个用于返回一个Mono或者Flux的repository。因此咱们仅仅经过该repository 就能够获得想要的。

固然你能够在这里经过响应式链式操做来作任何事。若是你须要,你能够对元素进行后置处理,此时事务会很智能的切换到一种不同的操做模式下,在这个事务操做背后,会有一个承载响应式链式执行事务信息的context 在操做调用之初就已经默默在背后运行了(译者注:底层是基于Spring Reactor的Context实现的)。这个repository操做在执行时会检测事务的context,而后在事务上下文中工做。在响应式链式操做执行完毕后跳出事务操做。可是要注意的一点,事务会在会在EventLoop中触发。这里,事务并非在调用该方法获得返回值时执行,而是在 pipeline(响应式链式)实际执行时,咱们才选择是提交仍是回滚(译者注:Context是基于订阅者的,只有发生订阅,才会有Context产生)。显而易见,Repository 实现须要有感知Transaction Context的特性,那就须要Repository 有专门的事务实现支持。

并且和标准的事务同样,你也须要有一个这样的Repository(好比基于JPA的实现,基于Hibernate的实现,基于JDBC的实现)能够很好的和事务一块儿使用,只不过限制有点多。咱们目前支持基于R2DBC的Repositories,它是咱们响应式关系型数据库链接的抽象实现。

R2DBC是Pivotal赞助的一个独立项目,同时咱们整合了大多数常见数据库的驱动实现,包括MongoDB。当发生数据存储的时候咱们有一个事务上下文模型,固然咱们也支持索引排列,这就是咱们在Spring Framework 5.2 中实现响应式事务支持所选择的方式。

关于事务背后的机制就到这里,咱们也明确的说起了R2DBC和MongoDB,它们背后的实现也不同。它们是不一样的SPI。若是你对整合这种响应式处理比较感兴趣,好比一些响应式的数据存储API。基于此你的主要精力应该放在ReactiveTransactionManager SPI上。 这是一个很不同的SPI。固然,也是由于这里它并不基于Threadlocal工做。它们在Spring MVC和Spring WebFlux中惟一有点像的地方在于它们都使用同样的注解。这是两种SPI,PlatformTransactionManager 是标准的基于Threadlocal绑定的事务处理机制。ReactiveTransactionManager则是基于响应式链式操做绑定的事务机制,使用了同样的注解配置来安装。

3. Reactive Messaging与RSocket

另一个值得一提的话题就是在Spring 5.2中才有的Reactive Messaging。Reactive Messaging使用起来很是简单。若是你有WebFlux的使用经验的话,这里它就和使用Endpoints是同样的,可是须要集成Spring Messaging模块。这样就能够经过上面的@MessageMapping注解并返回Reactive Stream Publisher来作到对Reactive Messaging的使用。关于这个消息集成模块,固然它能够和JMS同样,能够基于同步。在你使用这个消息技术时,你真正依赖的是底层的消息架构,咱们这里主要是基于RSocket这个响应式流处理模型。

RSocket也是一个行业合做所诞生的产物,不只仅是由Netifi(Rscoket公司)来为Rscoket提供基础开发(译者注:Spring旗下的Reactor-Netty是它的核心基础库)。因此RSocket是一个比较有趣的通讯模型,它能够经过响应式Endpoints(译者注:将请求路径和对应的处理类一块儿封装的一个类),来直接映射到RSocket的基础设施API,这是咱们为何推荐使用它。咱们打算自上而下进行响应式的支持。拿数据存储来说,你可使用支持响应式的Repository来进行数据存储操做。咱们想将响应式操做贯穿整个Spring操做栈,包括messaging endpoints 和web endpoints。这也是咱们的主要目标,对于此处的消息传递一样如此。整个过程基于一个像Rsocket同样的消息架构进行,即关于消息绑定和驱动都是基于响应式流的能力。而后你能够直接经过Spring 5.2 中的messaging endpoint来进行使用。

4. Reactive Application Event

在响应式介绍的最后,除了常见的针对请求的响应式编程处理,还有一个很棒的地方就是关于Application Events。关于ApplicationEvent这个基础类在Spring中已经存在好久了。传统的,事件监听器在不少状况下都是同步执行的,并不会阻塞操做。可是若是对ApplicationEventMulticaster进行线程池配置(调用setTaskExecutor设置),那就有可能在调用时产生阻塞。有不少事情依然能够经过ApplicationEvent来作到,可是有一件事作不到。就是对那些以返回值响应式类型的eventlistener方法实现的处理(看图中的@EventListener注解方法)。那咱们能够这样说,这里有一个事件,对应这个事件会有一个响应式的链式调用管道,你应该将它们集成到你的事件广播中,这也是咱们在Spring 5.2中正努力作到的事情。它尚未彻底可用,即你可使用一个Mono类型或CompletableFuture类型的返回值来表达说。我是一个EventListener,我能够作到异步或响应式链式执行。当Multicaster看到这个事件信号时,就会根据条件判断选择这个最合适的EventListener对事件进行处理。因此关于Application Events这块儿实际上是Spring整个响应式迭代过程当中的最后一块拼图。主要也是因为它在架构中常常用到,那若是使用响应式开发的话也不会例外。

你能够看到,我前面提到的这些代码(如Mono、Flux)都是基于Spring Reactor 的API。你也可使用Rxjava的Single和Flowable API。在不少状况下,你也能够用CompletableFuture,但没有背压支持,就是一个单个元素,可是它也能够被适配转换到响应式链式处理中,并运行在Netty的一个eventloop中。咱们底层有一套能够将它自动转换为响应式API类型的实现。并且这套实现已经存在好久了,能够很好的处理RxJava 和JDK 9 下的java.util.concurrent.Flow API类型或其余响应式publisher实现。

咱们即将在Spring 5.2中加入全新的Kotlin协程支持,也是基于响应式API来适配的。在Kotlin中,协程是Kotlin语言的基本功能,做为一种可挂起的方法。与之伴随的是Kotlin的底层API —— CoroutineContext。CoroutineContext实际上很是接近响应式模型。咱们在Spring Framework 5.2中将CoroutineContext直接适配到咱们的响应式架构中。所以,你也能够选择基于Reactor或响应式的API来使用Kotlin的协程。同时咱们自动的将它们适配到咱们的响应式请求路径处理(Endpoint)中,底层作了一些API适配和一些Kotlin扩展。在Spring Framework 5.2版本中咱们将加入Kotlin协程支持。

so,我基本上已经讲完了我想说的。谈到这里,我但愿前面的内容多少能引发你的兴趣。这也是咱们去年谈过的一些内容,咱们在响应式架构上作了不少的改进。依靠Java 8 API进行更全面更普遍的改进,使用了Java 8语言的特性,并对注解处理进行了彻底从新实现。特别是在性能调优、启动性能调优、热点性能调优等方面,经过这些改进容许咱们为你提供一个更好的性能体验。基本上Spring Framework 5.2 RC1版本会在七月份出来。GA版本计划在九月上旬发布,在此以后会发布SpringBoot 2.2的新版本。OK,这就是我今天想要带给大家的。感谢各位的参与,若是各位有任何疑问,在演讲结束后我很乐意为各位解答。再次感谢并但愿大家能享受接下来的show。

更多请关注咱们的公众号:

相关文章
相关标签/搜索