Java 晋级:Spring 5.0 之 WebFlux 整体认识
Spring Framework5.0 之后,Reactive Programming 进入的大家的视野,而 Spring Framework 5.0 的 Webflux 提供了 Reactive 的框架解决方案,通过本篇 chat,作者希望能和大家一起完整的认识 Spring WebFlux 和响应式编程。
优秀的程序员,特别是做到一定程度的时候你会发现基本上身上都有一个优秀的品质:就是遇到一件事情的时候后非要给它搞明白,而对整体有个完整的认识,本篇 chat 就和大家一起从整体到局部,从术到道的认识。
WebFlux 涉及到的概念认识(面向对象编程、函数式编程、响应式编程)?
1.面向对象编程(Object - Oriented Programming):万物皆对象,这个主要是我们把相似特性的事物进行抽象和封装,学 java 的应该都不陌生。面向对象的程序设计方法强调直接以现实世界中的物体为中心来思考和认识问题,并按照这些事物的本质特征把它们抽象为类。采用数据抽象和数据隐藏,类之间互相交互,共同构成大型的面向对象基础。
而在此之前还有一种编程思想面向过程:采用自顶向下、分而治之的方法,将整个程序按功能划分为几个可独立编程的子过程模块,每一子模块完成指定的子任务,主过程通过调用各子过程完来成全部处理工作,面向过程有点类似于初级程序员刚入门写了一大堆 if else 那种判断逻辑的感觉。
2.函数式编程(functional programming):故名思意,以函数为中心,函数成为关心的重点,而在 java 1.8 之前还完全不支持,Java 8 引入了 Lambda 表达式和 Stream API,java 同胞们才对函数编程起了兴趣,而 Lambda 是用函数贯穿整个流的操作。
3.面向事件编程:有的时候也叫面向钩子编程,界面编程中有各种各样的元素,有看得见的,例如按钮、输入框,也有看不见的,例如 Socket 、异常。而这些元素下挂满了各式各样的构子(事件)例如常见的 “ click ” 等等。
4.反应式编程(Reactive Programming):是一种基于数据流(data stream)和变化传递(propagation of change)的声明式(declarative)的编程范式。这句话概括的非常经典,有声明式的函数,值进行变化的传递流式编程方法。
5.响应式流(Reactive Stream):具备 “ 异步非阻塞”特性和“流量控制 ” 能力的数据流,我们称之为响应式流(Reactive Stream)。Web 应用具有 I/O 密集的特点,I/O 阻塞会带来比较大的性能损失或资源浪费,我们需要一种异步非阻塞的响应式的库,从而相继诞生了 RxJava 和 Reactor 两大开源 java 响应式流项目;
Java 社区的一些大牛制定了一个响应式流规范:
1,ReactiveX http://reactivex.io/(Reactive Extensions,Rx),它最初是 LINQ 的一个扩展,由微软的架构师 Erik Meijer 领导的团队开发,在 2012 年 11 月开源,Rx 是一个编程模型,目标是提供一致的编程接口,帮助开发者更方便的处理异步数据流,Rx 库支持 .NET、JavaScript 和 C++,Rx 近几年越来越流行了,现在已经支持几乎全部的流行编程语言了,包括 RxJS、RxJava 等。
先有的 RxReactive 1 后有的 响应式流规范,后来 RxJava 2 对响应式规范进行了兼容。
2,Reactor https://github.com/reactor/reactor是 Pivotal 旗下的项目,与大名鼎鼎的 Spring 是兄弟关系,因此是 Spring 近期推出的响应式模块 WebFlux 的 “ 御用 ” 响应式流。Reactor 支持响应式流规范,与 RxJava 相比,它没有任何历史包袱,专注于 Server 端的响应式开发,而 RxJava 更多倾向于 Android 端的响应式开发。
3,在 Java 9 版本中,响应式流的规范被纳入到了 JDK 中,相应的 API 接口是java.util.concurrent.Flow。
reactive - stream 所谓的规范就是定义了一些接口,如下:
(放大查看~)
JDK9 中的约定接口如下:(将 react stream 放到了 并发包下面,足可以看出主要是解决并发编程问题的)
6.反应式系统(Reactive System):使用反应式方式构建的:即时响应性(Responsive)、回弹性(Resilient)、弹性(Elastic)以及消息驱动(Message Driven)这样的系统,我们称之为反应式系统(Reactive System)。业内大佬正逐渐推反应式系统,但是目前还不是特别成熟,后面文章中给大家提到。业界大佬联名签署的反应式宣言。
其实从前端到后端,各个技术领域都有相应的反应式系统的开源项目和解决方案,只是还没有完全的贯穿下来;
WebFlux 中 Reactive 重要的封装是什么?
1,我们先来看下 reactive 的简单 demo
//引入 jar
<groupId>io.projectreactor</groupId>
<artifactId>reactor-core</artifactId>//Flux demo
Flux.just(1, 2, 3, 4, 5, 6).subscribe(
System.out::println,
System.err::println,
() -> System.out.println("Completed!"));//Mono error demo
Mono.error(new Exception("some error")).subscribe(
System.out::println,
System.err::println,
() -> System.out.println("Completed!")
);
2,spring webflux 实例
//添加依赖
dependencies {
compile('org.springframework.boot:spring-boot-starter-webflux')
}//添加TimeHandler类,模拟service操作@Componentpublic class TimeHandler {
public Mono<ServerResponse> getTime(ServerRequest serverRequest) {
return ok().contentType(MediaType.TEXT_PLAIN).body(Mono.just("Now is " + new SimpleDateFormat("HH:mm:ss").format(new Date())), String.class);
}
public Mono<ServerResponse> getDate(ServerRequest serverRequest) {
return ok().contentType(MediaType.TEXT_PLAIN).body(Mono.just("Today is " + new SimpleDateFormat("yyyy-MM-dd").format(new Date())), String.class);
}
public Mono<ServerResponse> sendTimePerSec(ServerRequest serverRequest) {
//模拟异步线程动态改变Flux结果
StringBuilder result = new StringBuilder("abc");
Thread thread = new Thread() {
public void run() {
for (int i = 0; i < 100; i++) {
result.append(i);
try {
Thread.sleep(500L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
thread.start();
return ok().contentType(MediaType.TEXT_EVENT_STREAM).body( // 1
Flux.interval(Duration.ofSeconds(1)). // 2
map(l -> new SimpleDateFormat("HH:mm:ss").format(new Date()) + result.toString()), String.class);
}
}//添加路由类似Controller@Configurationpublic class RouterConfig {
@Autowired
private TimeHandler timeHandler;
@Bean
public RouterFunction<ServerResponse> timerRouter() {
return route(GET("/time"), req -> timeHandler.getTime(req))
.andRoute(GET("/date"), timeHandler::getDate) // 这种方式相对于上一行更加简洁
.andRoute(GET("/times"), timeHandler::sendTimePerSec); // 增加这一行
}
}
演示结果如下:
ps:和 spring data 的关系接着后面看
3,那么 webflux 干了什么事情呢?
正如图所示,帮我们在 Reactor 的基础上帮我们做成 mvc 的响应式框架,包含各种路由,异步处理及其各种异步容器的支持;
我们通过依赖关系也可以发现很多事情:
内容未完
扫码继续阅读