1.3.3 Spring WebFluxSpring WebFlux是随Spring 5推出的响应式Web框架。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服务端开发。由此看来,Spring WebFlux与Vert.x有一些相通之处,都是建立在非阻塞的异步I/O和事件驱动的基础之上的。2、响应式Http客户端此外,Spring WebFlux也提供了一个响应式的Http客户端API WebClient。它可以用函数式的方式异步非阻塞地发起Http请求并处理响应。其底层也是由Netty提供的异步支持。我们可以把WebClient看做是响应式的RestTemplate,与后者相比,前者:是非阻塞的,可以基于少量的线程处理更高的并发;可以使用Java 8 lambda表达式;支持异步的同时也可以支持同步的使用方式;可以通过数据流的方式与服务端进行双向通信。当然,与服务端对应的,Spring WebFlux也提供了响应式的Websocket客户端API。简单介绍这些,让我们来Coding吧(本文源码)~本节,我们仍然是本着“Hello,world!”的精神来上手熟悉WebFlux,因此暂时不会像手册一样面面俱到地谈到WebFlux的各个细节,我们通过以下几个例子来了解它:先介绍一下使用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在内的响应式模块。Spring Boot 2即将发布正式版,不过目前的版本从功能上已经完备,下边的例子我们就用Spring Boot 2在进行搭建。1.3.3.1 基于WebMVC注解的方式我们首先用Spring WebMVC开发一个只有Controller层的简单的Web服务,然后仅仅做一点点调整就可切换为基于Spring WebFlux的具有同样功能的Web服务。我们使用Spring Boot 2搭建项目框架。以下截图来自IntelliJ IDEA,不过其他IDE也都是类似的。1、基于Spring Initializr创建项目本节的例子很简单,不涉及Service层和Dao层,因此只选择spring-webmvc即可,也就是“Web”的starter。也可以使用网页版的https://start.spring.io来创建项目:创建后的项目POM中,包含下边的依赖,即表示基于Spring WebMVC: <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>2、创建Controller和Endpoint创建Controller类HelloController,仅提供一个Endpoint:/hello: @RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Welcome to reactive world ~";
}
}3)启动应用OK了,一个简单的基于Spring WebMVC的Web服务。我们新增了HelloController.java,修改了application.properties。使用IDE启动应用,或使用maven命令:mvn spring-boot:run通过打印的log可以看到,服务运行于Tomcat的8080端口:测试Endpoint。在浏览器中访问http://localhost:8080/hello,或运行命令:curl http://localhost:8080/hello返回Welcome to reactive world ~。基于Spring WebFlux的项目与上边的步骤一致,仅有两点不同。我们这次偷个懒,就不从新建项目了,修改一下上边的项目:4、依赖“Reactive Web”的starter而不是“Web”修改项目POM,调整依赖使其基于Spring WebFlux: <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId> <!–【改】增加“flux”四个字符–>
</dependency>5、Controller中处理请求的返回类型采用响应式类型 @RestController
public class HelloController {
@GetMapping("/hello")
public Mono<String> hello() { // 【改】返回类型为Mono<String>
return Mono.just("Welcome to reactive world ~"); // 【改】使用Mono.just生成响应式数据
}
}6、启动应用仅需要上边两步就改完了,是不是很简单,同样的方法启动应用。启动后发现应用运行于Netty上:访问http://localhost:8080/hello,结果与Spring WebMVC的相同。7)总结从上边这个非常非常简单的例子中可以看出,Spring真是用心良苦,WebFlux提供了与之前WebMVC相同的一套注解来定义请求的处理,使得Spring使用者迁移到响应式开发方式的过程变得异常轻松。虽然我们只修改了少量的代码,但是其实这个简单的项目已经脱胎换骨了。整个技术栈从命令式的、同步阻塞的【spring-webmvc + servlet + Tomcat】变成了响应式的、异步非阻塞的【spring-webflux + Reactor + Netty】。Netty是一套异步的、事件驱动的网络应用程序框架和工具,能够开发高性能、高可靠性的网络服务器和客户端程序,因此与同样是异步的、事件驱动的响应式编程范式一拍即合下边的内容了解即可,就不实战了。在Java 7推出异步I/O库,以及Servlet3.1增加了对异步I/O的支持之后,Tomcat等Servlet容器也随后开始支持异步I/O,然后Spring WebMVC也增加了对Reactor库的支持,所以上边第4)步如果不是将spring-boot-starter-web替换为spring-boot-starter-WebFlux,而是增加reactor-core的依赖的话,仍然可以用注解的方式开发基于Tomcat的响应式应用。说明:本文限于篇幅,故而只展示部分的java内容,最后给大家分享Spring系列的学习笔记和面试题,包含spring面试题、spring cloud面试题、spring boot面试题、spring教程笔记、spring boot教程笔记、最新阿里巴巴开发手册(63页PDF总结)、2022年Java面试手册。一共整理了1184页PDF文档。私信博主(777)领取,祝大家更上一层楼!!!
本文出自快速备案,转载时请注明出处及相应链接。