Spring WebFlux

一、SpringWebflux 介绍

Webflux 是 Spring5 中新添加的模块,用于 web 开发,功能和 SpringMVC 类似,Webflux 是一种响应式编程框架。

传统 web 框架,比如 SpringMVC,这些基于 Servlet 容器,Webflux 是一种异步非阻塞的框架,异步非阻塞的框架在 Servlet3.1 以后才支持,核心是基于 Reactor 的相关 API 实现的。

Webflux 特点:

  1. 非阻塞式:在有限资源下,提高系统吞吐量和伸缩性,以 Reactor 为基础实现响应式编程
  2. 函数式编程:Spring5 框架基于 java8,Webflux 使用 Java8 函数式编程方式实现路由请求

对比 SpringMVC

  1. 两个框架都可以使用注解方式,都运行在 Tomcat 等容器中
  2. SpringMVC 采用命令式编程,Webflux 采用异步响应式编程

二、响应式编程

响应式编程是一种面向数据流和变化传播的编程范式。这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。

  1. 响应式编程操作中,Reactor 是满足 Reactive 规范框架
  2. Reactor 有两个核心类,Mono 和 Flux,这两个类实现接口 Publisher,提供丰富操作符。Flux 对象实现发布者,返回 N 个元素;Mono 实现发布者,返回 0 或者 1 个元素
  3. Flux 和 Mono 都是数据流的发布者,使用 Flux 和 Mono 都可以发出三种数据信号: 元素值,错误信号,完成信号。错误信号和完成信号都代表终止信号,终止信号用于告诉订阅者数据流结束了,错误信号终止数据流同时把错误信息传递给订阅者

Mono

Flux

  1. 代码演示 Flux 和 Mono

    引入依赖

    <dependency><groupId>io.projectreactor</groupId><artifactId>reactor-core</artifactId><version>3.1.5.RELEASE</version>
    </dependency>
    

    示例代码

            //just 方法直接声明Flux.just(1,2,3,4).subscribe(System.out::println);Mono.just(1);//其他的方法Integer[] array = {1,2,3,4};Flux.fromArray(array);List<Integer> list = Arrays.asList(array);Flux.fromIterable(list);Stream<Integer> stream = list.stream();Flux.fromStream(stream);
    

    调用 just 或者其他方法只是声明数据流,数据流并没有发出,只有进行订阅之后才会触发数据流,不订阅什么都不会发生的。

  2. 三种信号特点

    1. 错误信号和完成信号都是终止信号,不能共存
    2. 如果没有发送任何元素值,而是直接发送错误或者完成信号,表示是空数据流
    3. 如果没有错误信号,没有完成信号,表示是无限数据流
  3. 操作符

    对数据流进行一道道操作,成为操作符,比如工厂流水线

    • map 元素映射为新元素

    • flatMap 元素映射为流

    把每个元素转换成流,把转换之后的多个流合并成大的流

三、SpringWebflux 执行流程和核心 API

SpringWebflux 基于 Reactor,默认使用容器是 Netty,Netty 是高性能的 NIO 框架,异步非阻塞的框架

BIO模型

NIO模型

SpringWebflux 执行过程和 SpringMVC 相似的:

SpringWebflux 核心控制器 DispatcherHandler,实现接口 WebHandler,接口 WebHandler 有一个handle方法处理web请求

handle方法在DispatcherHandler中的实现

  • HandlerMapping:定义请求和处理对象的映射关系
  • HandlerAdapter:请求处理
  • HandlerResultHandler:响应结果处理

四、SpringWebflux(基于注解编程模型)

添加依赖

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

创建实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {private String name;private Integer age;
}

创建接口定义操作方法

public interface PersonService {//根据 id 查询用户Mono<Person> getPersonById(int id);//查询所有用户Flux<Person> getAllPerson();//添加用户Mono<Void> savePersonInfo(Mono<Person> Person);
}

接口实现

@Service
public class PersonServiceImpl implements PersonService {//创建 map 集合存储数据private final static Map<Integer,Person> users = new HashMap<>();static {users.put(1,new Person("lucy",20));users.put(2,new Person("mary",30));users.put(3,new Person("jack",50));}@Overridepublic Mono<Person> getPersonById(int id) {return Mono.justOrEmpty(users.get(id));}@Overridepublic Flux<Person> getAllPerson() {return Flux.fromIterable(users.values());}@Overridepublic Mono<Void> savePersonInfo(Mono<Person> personMono) {return personMono.doOnNext(person -> {int id = users.size()+ 1;users.put(id, person);}).thenEmpty(Mono.empty());}
}

创建controller

@RestController
public class PersonController {@Autowiredprivate PersonService personService;//id 查询@GetMapping("/person/{id}")public Mono<Person> getPersonId(@PathVariable int id) {return personService.getPersonById(id);}//查询所有@GetMapping("/person")public Flux<Person> getPersons() {return personService.getAllPerson();}//添加@PostMapping("/savePerson")public Mono<Void> savePerson(@RequestBody Person Person) {Mono<Person> PersonMono = Mono.just(Person);return personService.savePersonInfo(PersonMono);}}

五、SpringWebflux(基于函数式编程模型)

基于函数式编程模型时候,有两个核心接口:

RouterFunction(实现路由功能,请求转发给对应的 handler)

HandlerFunction(处理请求生成响应)

创建handle

@Component
public class PersonHandle {@Autowiredprivate PersonService personService;public Mono<ServerResponse> getPersonId(ServerRequest request) {//获取 id 值int userId = Integer.valueOf(request.pathVariable("id"));//空值处理Mono<ServerResponse> notFound = ServerResponse.notFound().build();//调用 service 方法得到数据Mono<Person> userMono = personService.getPersonById(userId);//把 userMono 进行转换返回//使用 Reactor 操作符 flatMapreturn userMono.flatMap(person -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(fromObject(person)).switchIfEmpty(notFound));}public Mono<ServerResponse> getAllPerson(ServerRequest request) {Flux<Person> allPerson = personService.getAllPerson();return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(allPerson, Person.class);}public Mono<ServerResponse> savePerson(ServerRequest request) {Mono<Person> personMono = request.bodyToMono(Person.class);return ServerResponse.ok().build(personService.savePersonInfo(personMono));}
}

创建router

@Configuration
public class RouterConfig {@Autowiredprivate PersonHandle personHandle;@Beanpublic RouterFunction<ServerResponse> testRouter() {return RouterFunctions.route(RequestPredicates.GET("fun/person/{id}"), personHandle::getPersonId).andRoute(RequestPredicates.GET("fun/person"), personHandle::getAllPerson).andRoute(RequestPredicates.POST("fun/savePerson"), personHandle::savePerson);}}

Spring WebFlux入门相关推荐

  1. springboot异步注解_Spring Boot 2 :Spring Boot 中的响应式编程和 WebFlux 入门

    [小宅按]Spring 5.0 中发布了重量级组件 Webflux,拉起了响应式编程的规模使用序幕. WebFlux 使用的场景是异步非阻塞的,使用 Webflux 作为系统解决方案,在大多数场景下可 ...

  2. (转)Spring Boot 2 (十):Spring Boot 中的响应式编程和 WebFlux 入门

    http://www.ityouknow.com/springboot/2019/02/12/spring-boot-webflux.html Spring 5.0 中发布了重量级组件 Webflux ...

  3. Spring Boot WebFlux 入门

    1. 概述 友情提示:Reactive Programming ,翻译为反应式编程,又称为响应式编程.本文,我们统一使用响应式.不过,比较正确的叫法还是反应式. Spring Framework 5  ...

  4. Spring 5 WebFlux入门教程

    WebFlux是Spring 5 新增特性,提供响应式web应用.本文我们利用RestController 和 WebClient组件实现简单的响应式Restful应用. Spring WebFlux ...

  5. Spring Webflux – Kotlin DSL –实现的演练

    在先前的博客文章中,我描述了Spring Web Framework中的响应式编程支持Spring Webflux如何使用基于Kotlin的DSL使用户能够以非常直观的方式描述路由. 在这里,我想探索 ...

  6. SpringBoot2.0使用Spring WebFlux之HelloWord篇

    SpringBoot2.0使用Spring WebFlux之HelloWord篇 Reactive Programming和Reactive Streams 以及 Spring Webflux 介绍 ...

  7. Spring Boot 3.x 系列【23】集成Spring WebFlux开发响应式应用程序

    有道无术,术尚可求,有术无道,止于术. 本系列Spring Boot版本3.0.4 源码地址:https://gitee.com/pearl-organization/study-spring-boo ...

  8. Spring Cloud入门系列(1)- Spring生态体系发展史+全系框架介绍

    Spring发展史 2000年,Java EE和EJB迅速发展,很多知名公司都是采用此技术方案进行项目开发,但是EJB 属于重量级框架,开发繁琐.于是一个叫Rod Johnson的大佬写了一本叫做&l ...

  9. Spring Cloud入门-Gateway服务网关(Hoxton版本)

    文章目录 Spring Cloud入门系列汇总 摘要 Gateway 简介 相关概念 创建 api-gateway模块 在pom.xml中添加相关依赖 两种不同的配置路由方式 使用yml配置 使用Ja ...

最新文章

  1. 从乘法表JAVA意思4_四、Java从头开始-我的九九乘法表(二)
  2. MIT“人造肌肉”登上Science封面,能提起自重650倍的物体,伸缩10000次都不坏
  3. shader 编程入门(一)
  4. c++ primer 5th,习题13.3 答案是不是错了?(未解决)
  5. Python编程基础20:实例成员与类成员
  6. access后台链接mysql_Access为后台数据库的网站统计系统
  7. 读《scikiit-learn机器学习》黄永昌第五章
  8. 拷贝一个用户下的所有表和数据到另外一个库
  9. [Unity] 3D数学基础 - 2D旋转矩阵
  10. 太原计算机专业学校在哪里,太原信息技术学校在哪里
  11. python 004 __小斌文档 | 判断和循环
  12. 键盘定位板图纸_DIY如何自制专属GH60机械键盘教程【步骤详解】
  13. 倾斜摄影超大场景的三维模型的顶层合并常见的问题分析
  14. 用大数据建设“安全”生态 亿赛通出席安徽省通信学会大数据学术交流会
  15. 外媒关注:中国版Twitter新浪微博推出微米对抗微信
  16. 投资理财-股市是称重机吗?
  17. 超级实用的PLSQLDEV客户端总结
  18. 油品调和计算软件_油品调和计算
  19. HMaster因zookeeper连接超时自杀
  20. 车品觉:忘掉大数据,数据思维才最重要 !

热门文章

  1. 忘记PPT密码怎么办?附解决办法
  2. Apache Commons Lang3 DateUtils用法
  3. Python lDLE软件实现清屏功能
  4. ArcGis安装失败提示“需要Microsoft .NET Framework 3.5 sp1或等效环境”的解决方法
  5. OpenFile函数使用说明
  6. 2023年mathorcup杯A题代码小技巧总结
  7. maven卸载强制性依赖
  8. java 文件目录是否存在_java中判断文件目录是否存在的方法
  9. 仿大众点评——秒杀系统部分01
  10. 【Presto】URLDecoder: Illegal hex characters in escape (%) pattern 错误处理