【Spring Boot 2.0学习之旅-15】SpringBoot2.0响应式编程

本文介绍SpringBoot2.0响应式编程的基础知识,并通过实战演示如何使用SpringWebFlux创建非阻塞式Web应用。文章对比了SpringMVC与SpringWebFlux的不同之处,并探讨了它们各自的应用场景。

SpringBoot2.0响应式编程

一、SpringBoot2.0 响应式编程基础知识

Spring WebFlux官方文档

SpringBoot WebFlux文档

1.什么是Spring WebFlux?

在这里插入图片描述

在了解Spring WebFlux之前,我们先来对比说说什么是Spring MVC,这更有益我们去理解WebFlux。下面是对Spring MVC的定义,如下:

Spring MVC is built on the Servlet API and uses a synchronous blocking I/O architecture whth a one-request-per-thread model.

Spring MVC 构建于 Servlet API 之上,使用的是同步阻塞式 I/O 模型,什么是同步阻塞式 I/O 模型呢?就是说,每一个请求对应一个线程去处理

了解了 Spring MVC 之后,再来说说 Spring WebFlux:

Spring WebFlux is a non-blocking web framework built from the ground up to take advantage of multi-core, next-generation processors and handle massive numbers of concurrent connections.

Spring WebFlux 是一个异步非阻塞式的 Web 框架,它能够充分利用多核 CPU 的硬件资源去处理大量的并发请求

2.WebFlux的优势&优势性能

WebFlux 内部使用的是响应式编程(Reactive Programming),以 Reactor 库为基础, 基于异步和事件驱动,可以让我们在不扩充硬件资源的前提下,提升系统的吞吐量和伸缩性。

看到这里,你是不是以为 WebFlux 能够使程序运行的更快呢?量化一点,比如说我使用 WebFlux 以后,一个接口的请求响应时间是不是就缩短了呢?

抱歉了,答案是否定的!以下是官方原话:

Reactive and non-blocking generally do not make applications run faster.

WebFlux 并不能使接口的响应时间缩短,它仅仅能够提升吞吐量和伸缩性

3.WebFlux应用场景

上面说到了, Spring WebFlux 是一个异步非阻塞式的 Web 框架,所以,它特别适合应用在 IO 密集型的服务中,比如微服务网关这样的应用中。

PS: IO 密集型包括:磁盘IO密集型, 网络IO密集型,微服务网关就属于网络 IO 密集型,使用异步非阻塞式编程模型,能够显著地提升网关对下游服务转发的吞吐量。

在这里插入图片描述

4.选WebFlux还是Spring MVC

首先你需要明确一点就是:WebFlux 不是 Spring MVC 的替代方案!,虽然 WebFlux 也可以被运行在 Servlet 容器上(需是 Servlet 3.1+ 以上的容器),但是 WebFlux 主要还是应用在异步非阻塞编程模型,而 Spring MVC 是同步阻塞的,如果你目前在 Spring MVC 框架中大量使用非同步方案,那么,WebFlux 才是你想要的,否则,使用 Spring MVC 才是你的首选。

在微服务架构中,Spring MVC 和 WebFlux 可以混合使用,比如已经提到的,对于那些 IO 密集型服务(如网关),我们就可以使用 WebFlux 来实现。

选 WebFlux 还是 Spring MVC? This is not a problem!

总之一句话,在合适的场景中,选型最合适的技术。

5.Spring MVC和Spring WebFlux异同点

在这里插入图片描述

从上图中,可以一眼看出 Spring MVC 和 Spring WebFlux 的相同点和不同点:

相同点

  • 都可以使用 Spring MVC 注解,如 @Controller, 方便我们在两个 Web 框架中自由转换;
  • 均可以使用 Tomcat, Jetty, Undertow Servlet 容器(Servlet 3.1+);

注意点

  • Spring MVC 因为是使用的同步阻塞式,更方便开发人员编写功能代码,Debug 测试等,一般来说,如果 Spring MVC 能够满足的场景,就尽量不要用 WebFlux;
  • WebFlux 默认情况下使用 Netty 作为服务器;
  • WebFlux 不支持 MySql;

在 WebFlux 中,除了 Mono 外,还有一个 Flux,不同的是:

  • Mono:返回 0 或 1 个元素,即单个对象。
  • Flux:返回 N 个元素,即 List 列表对象。

二、SpringBoot2.x webflux实战

1.添加webflux依赖

新建一个 Spring Boot 项目,在 pom.xml 文件中添加 webflux 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

在这里插入图片描述

2.定义接口

新建一个 controller 包,用来放置对外的接口类,再创建一个 WebFluxController 类,定义两个接口:

package com.lcz.spring_demo21.controller;

import com.lcz.spring_demo21.entity.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

/**
 * @author : codingchao
 * @date : 2021-12-24 14:05
 * @Description:
 **/

@RestController
public class WebFluxController {

    @GetMapping("/hello")
    public String hello(){
        return "Hello,WebFlux!";
    }

    @GetMapping("/user")
    public Mono<User> getUser(){
        User user = new User();
        user.setName("LCZ");
        user.setDesc("LCZ的Java自习室!!!");
        return Mono.just(user);
    }
}

package com.lcz.spring_demo21.entity;

/**
 * @author : codingchao
 * @date : 2021-12-24 14:07
 * @Description:
 **/
public class User {
    private String name;
    private String desc;

    public User(){

    }
    public User(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}

以上控制器类中,我们使用的全都是 Spring MVC 的注解,分别定义了两个接口:

  • 一个 GET 请求的 /hello 接口,返回 Hello, WebFlux !字符串。
  • 又定义了一个 GET 请求的 /user方法,返回的是 JSON 格式 User 对象。

这里注意,User 对象是通过 Mono 对象包装的,你可能会问,为啥不直接返回呢?

在 WebFlux 中,Mono 是非阻塞的写法,只有这样,你才能发挥 WebFlux 非阻塞 + 异步的特性。

在 WebFlux 中,除了 Mono 外,还有一个 Flux,不同的是:

  • Mono:返回 0 或 1 个元素,即单个对象。
  • Flux:返回 N 个元素,即 List 列表对象。

3.测试接口

启动项目,查看控制台输出:

在这里插入图片描述

当控制台中输出中包含 Netty started on port(s): 8080 语句时,说明默认使用 Netty 服务已经启动了。

先对 /hello 接口发起调用:

在这里插入图片描述

再来对 /user 接口测试一下:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mind_programmonkey

你的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值