Spring WebFlux入门
Spring WebFlux
一、SpringWebflux 介绍
Webflux 是 Spring5 中新添加的模块,用于 web 开发,功能和 SpringMVC 类似,Webflux 是一种响应式编程框架。
传统 web 框架,比如 SpringMVC,这些基于 Servlet 容器,Webflux 是一种异步非阻塞的框架,异步非阻塞的框架在 Servlet3.1 以后才支持,核心是基于 Reactor 的相关 API 实现的。
Webflux 特点:
- 非阻塞式:在有限资源下,提高系统吞吐量和伸缩性,以 Reactor 为基础实现响应式编程
- 函数式编程:Spring5 框架基于 java8,Webflux 使用 Java8 函数式编程方式实现路由请求
对比 SpringMVC
- 两个框架都可以使用注解方式,都运行在 Tomcat 等容器中
- SpringMVC 采用命令式编程,Webflux 采用异步响应式编程
二、响应式编程
响应式编程是一种面向数据流和变化传播的编程范式。这意味着可以在编程语言中很方便地表达静态或动态的数据流,而相关的计算模型会自动将变化的值通过数据流进行传播。
- 响应式编程操作中,Reactor 是满足 Reactive 规范框架
- Reactor 有两个核心类,Mono 和 Flux,这两个类实现接口 Publisher,提供丰富操作符。Flux 对象实现发布者,返回 N 个元素;Mono 实现发布者,返回 0 或者 1 个元素
- Flux 和 Mono 都是数据流的发布者,使用 Flux 和 Mono 都可以发出三种数据信号: 元素值,错误信号,完成信号。错误信号和完成信号都代表终止信号,终止信号用于告诉订阅者数据流结束了,错误信号终止数据流同时把错误信息传递给订阅者
Mono
Flux
代码演示 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 或者其他方法只是声明数据流,数据流并没有发出,只有进行订阅之后才会触发数据流,不订阅什么都不会发生的。
三种信号特点
- 错误信号和完成信号都是终止信号,不能共存
- 如果没有发送任何元素值,而是直接发送错误或者完成信号,表示是空数据流
- 如果没有错误信号,没有完成信号,表示是无限数据流
操作符
对数据流进行一道道操作,成为操作符,比如工厂流水线
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入门相关推荐
- springboot异步注解_Spring Boot 2 :Spring Boot 中的响应式编程和 WebFlux 入门
[小宅按]Spring 5.0 中发布了重量级组件 Webflux,拉起了响应式编程的规模使用序幕. WebFlux 使用的场景是异步非阻塞的,使用 Webflux 作为系统解决方案,在大多数场景下可 ...
- (转)Spring Boot 2 (十):Spring Boot 中的响应式编程和 WebFlux 入门
http://www.ityouknow.com/springboot/2019/02/12/spring-boot-webflux.html Spring 5.0 中发布了重量级组件 Webflux ...
- Spring Boot WebFlux 入门
1. 概述 友情提示:Reactive Programming ,翻译为反应式编程,又称为响应式编程.本文,我们统一使用响应式.不过,比较正确的叫法还是反应式. Spring Framework 5 ...
- Spring 5 WebFlux入门教程
WebFlux是Spring 5 新增特性,提供响应式web应用.本文我们利用RestController 和 WebClient组件实现简单的响应式Restful应用. Spring WebFlux ...
- Spring Webflux – Kotlin DSL –实现的演练
在先前的博客文章中,我描述了Spring Web Framework中的响应式编程支持Spring Webflux如何使用基于Kotlin的DSL使用户能够以非常直观的方式描述路由. 在这里,我想探索 ...
- SpringBoot2.0使用Spring WebFlux之HelloWord篇
SpringBoot2.0使用Spring WebFlux之HelloWord篇 Reactive Programming和Reactive Streams 以及 Spring Webflux 介绍 ...
- Spring Boot 3.x 系列【23】集成Spring WebFlux开发响应式应用程序
有道无术,术尚可求,有术无道,止于术. 本系列Spring Boot版本3.0.4 源码地址:https://gitee.com/pearl-organization/study-spring-boo ...
- Spring Cloud入门系列(1)- Spring生态体系发展史+全系框架介绍
Spring发展史 2000年,Java EE和EJB迅速发展,很多知名公司都是采用此技术方案进行项目开发,但是EJB 属于重量级框架,开发繁琐.于是一个叫Rod Johnson的大佬写了一本叫做&l ...
- Spring Cloud入门-Gateway服务网关(Hoxton版本)
文章目录 Spring Cloud入门系列汇总 摘要 Gateway 简介 相关概念 创建 api-gateway模块 在pom.xml中添加相关依赖 两种不同的配置路由方式 使用yml配置 使用Ja ...
最新文章
- 从乘法表JAVA意思4_四、Java从头开始-我的九九乘法表(二)
- MIT“人造肌肉”登上Science封面,能提起自重650倍的物体,伸缩10000次都不坏
- shader 编程入门(一)
- c++ primer 5th,习题13.3 答案是不是错了?(未解决)
- Python编程基础20:实例成员与类成员
- access后台链接mysql_Access为后台数据库的网站统计系统
- 读《scikiit-learn机器学习》黄永昌第五章
- 拷贝一个用户下的所有表和数据到另外一个库
- [Unity] 3D数学基础 - 2D旋转矩阵
- 太原计算机专业学校在哪里,太原信息技术学校在哪里
- python 004 __小斌文档 | 判断和循环
- 键盘定位板图纸_DIY如何自制专属GH60机械键盘教程【步骤详解】
- 倾斜摄影超大场景的三维模型的顶层合并常见的问题分析
- 用大数据建设“安全”生态 亿赛通出席安徽省通信学会大数据学术交流会
- 外媒关注:中国版Twitter新浪微博推出微米对抗微信
- 投资理财-股市是称重机吗?
- 超级实用的PLSQLDEV客户端总结
- 油品调和计算软件_油品调和计算
- HMaster因zookeeper连接超时自杀
- 车品觉:忘掉大数据,数据思维才最重要 !
热门文章
- 忘记PPT密码怎么办?附解决办法
- Apache Commons Lang3 DateUtils用法
- Python lDLE软件实现清屏功能
- ArcGis安装失败提示“需要Microsoft .NET Framework 3.5 sp1或等效环境”的解决方法
- OpenFile函数使用说明
- 2023年mathorcup杯A题代码小技巧总结
- maven卸载强制性依赖
- java 文件目录是否存在_java中判断文件目录是否存在的方法
- 仿大众点评——秒杀系统部分01
- 【Presto】URLDecoder: Illegal hex characters in escape (%) pattern 错误处理