Spring WebFlux-快速上门(一)

Spring WebFlux是随Spring 5推出的响应式Web框架。


Spring WebFlux-快速上门(一)

1)服务端技术栈

Spring提供了完整的支持响应式的服务端技术栈。

如上图所示,左侧为基于spring-webmvc的技术栈,右侧为基于spring-webflux的技术栈,

Spring WebFlux是基于响应式流的,因此可以用来建立异步的、非阻塞的、事件驱动的服务。它采用Reactor作为首选的响应式流的实现库,不过也提供了对RxJava的支持。

由于响应式编程的特性,Spring WebFlux和Reactor底层需要支持异步的运行环境,比如Netty和Undertow;也可以运行在支持异步I/O的Servlet 3.1的容器之上,比如Tomcat(8.0.23及以上)和Jetty(9.0.4及以上)。

从图的纵向上看,spring-webflux上层支持两种开发模式:

类似于Spring WebMVC的基于注解(@Controller、@RequestMapping)的开发模式;

Java 8 lambda 风格的函数式开发模式。

Spring WebFlux也支持响应式的Websocket服务端开发。

2)响应式Http客户端

此外,Spring WebFlux也提供了一个响应式的Http客户端API WebClient。它可以用函数式的方式异步非阻塞地发起Http请求并处理响应。其底层也是由Netty提供的异步支持。

我们可以把WebClient看做是响应式的RestTemplate,与后者相比,前者:

是非阻塞的,可以基于少量的线程处理更高的并发;

可以使用Java 8 lambda表达式;

支持异步的同时也可以支持同步的使用方式;

可以通过数据流的方式与服务端进行双向通信。

当然,与服务端对应的,Spring WebFlux也提供了响应式的Websocket客户端API。

我们通过以下几个例子来了解它:

先介绍一下使用Spring WebMVC风格的基于注解的方式如何编写响应式的Web服务,这几乎没有学习成本,非常赞。虽然这种方式在开发上与Spring WebMVC变化不大,但是框架底层已经是完全的响应式技术栈了;

再进一步介绍函数式的开发模式;

简单几行代码实现服务端推送(Server Send Event,SSE);

然后我们再加入响应式数据库的支持(使用Reactive Spring Data for MongoDB);

使用WebClient与前几步做好的服务端进行通信;

最后我们看一下如何通过“流”的方式在Http上进行通信。

Spring Boot 2是基于Spring 5的,其中一个比较大的更新就在于支持包括spring-webflux和响应式的spring-data在内的响应式模块。

基于WebMVC注解的方式

我们首先用Spring WebMVC开发一个只有Controller层的简单的Web服务,然后仅仅做一点点调整就可切换为基于Spring WebFlux的具有同样功能的Web服务。

基于Spring Initializr创建项目

本节的例子很简单,不涉及Service层和Dao层,因此只选择spring-webmvc即可,也就是“Web”的starter;


Spring WebFlux-快速上门(一)

也可以自行在pom上加上依赖:

<code>

<

dependency

>

<

groupId

>

org.springframework.boot

groupId

>

<

artifactId

>

spring-boot-starter-web

artifactId

>

dependency

>

/<code>

创建Controller和Endpoint

创建Controller类HelloController,仅提供一个Endpoint:/hello:

<code>@RestController/<code>
<code>    

public

class

HelloController

{

/<code>
<code>        /<code>
<code>        

public

String

hello

()

{/<code>
<code>            

return

"Welcome to reactive world ~"

;/<code>
<code>        }/<code>
<code>    }/<code>

启动应用

一个简单的基于Spring WebMVC的Web服务。我们新增了HelloController.java,修改了application.properties。


Spring WebFlux-快速上门(一)

使用IDE启动应用,或使用maven命令:mvn spring-boot:run

测试Endpoint。在浏览器中访问http://localhost:8080/hello

基于Spring WebFlux的项目与上边的步骤一致,仅有两点不同。我们这次偷个懒,就不从新建项目了,修改一下上边的项目:

依赖“Reactive Web”的starter而不是“Web”

修改pom:

<code>

/<code>
<code>        

<

groupId

>

org.springframework.boot

groupId

>

/<code>
<code>        

<

artifactId

>

spring-boot-starter-webflux

artifactId

>

/<code>
<code>    

/<code>

Controller中处理请求的返回类型采用响应式类型

<code>@RestController/<code>
<code>    

public

class

HelloController

{

/<code>
<code>        /<code>
<code>        

public

Mono

hello

(

)

{ /<code>
<code>            

return

Mono.just(

"Welcome to reactive world ~"

); /<code>
<code>        }/<code>
<code>    }/<code>

仅需要上边两步就改完了,是不是很简单,同样的方法启动应用。启动后发现应用运行于Netty上:


Spring WebFlux-快速上门(一)

访问http://localhost:8080/hello,结果与Spring WebMVC的相同。

从上边这个非常非常简单的例子中可以看出,Spring真是用心良苦,WebFlux提供了与之前WebMVC相同的一套注解来定义请求的处理,使得Spring使用者迁移到响应式开发方式的过程变得异常轻松。

虽然我们只修改了少量的代码,但是其实这个简单的项目已经脱胎换骨了。整个技术栈从命令式的、同步阻塞的【spring-webmvc + servlet + Tomcat】变成了响应式的、异步非阻塞的【spring-webflux + Reactor + Netty】。

Netty是一套异步的、事件驱动的网络应用程序框架和工具,能够开发高性能、高可靠性的网络服务器和客户端程序,因此与同样是异步的、事件驱动的响应式编程范式一拍即合。


分享到:


相關文章: