反应式的Spring 5
Posted 羊八井花园
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反应式的Spring 5相关的知识,希望对你有一定的参考价值。
Spring从5.0开始拥抱反应式(Reactive)开发,通过Reactor和WebFlux来支持反应式的开发模式。有关反应式更多的内容可以阅读 《反应式宣言》 。反应式系统具有以下物质:即时响应性(Responsive)、回弹性(Resilient)、弹性(Elastic)以及消息驱动(Message Driven)。对于这样的系统,我们称之为反应式系统(Reactive System)。这里,推荐一本对反应式讲得很好的书籍:《反应式设计模式》,可在 https://item.jd.com/12518824.html 购买。
Spring 5在传统的Servlet Stack之外提供了Reactive Stack来支持反应式的编程。Spring官方对Reactive Stack的说明为:Spring WebFlux是一个从头开始构建的无阻塞Web框架,它利用多核技术和下一代处理器来处理大量的并发连接。
WebFlux实现了Reactive Streams(反应式流处理),由 Project Reactor 提供支持。类似 Akka Stream 、RxJava 等其它实现了 Reactive Streams 规范的库,它提供了在JVM平台上构建非阻塞应用的强大工具。
起步
本文不是反应式编程原理的介绍及说明文章,本文只是告诉你怎样在Spring生态中起步反应式编程。简单说就是怎样使用Spring 5新推出的WebFlux来进行应用开发。本文使用Maven做为示例的构建工具,需要引入spring-boot-starter-webflux
来代替传统的基于Servlet模型的spring-boot-starter-web
依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
你可以在 https://github.com/yangbajing/spring-reactive-
sample/blob/master/pom.xml 找到完整的配置。
Spring Boot 2默认未启用WebFlux特性,需要使用@EnableWebFlux
注解来启用,通常可以在一个@Configuration
上配置:
@EnableWebFlux
@Configurationpublic class WebConfiguration {
}
请求与响应
对应请求、响应(Request/Response),WebFlux提供了两种实现方式:
类似WebMVC的基于注解的控制器方式
全新的函数式端点方式(类似Akka HTTP Routing那样通过函数来组合定义HTTP路由)
本文将介绍基于注解的控制器方式。
@GetMapping(path = "world")
public Hello world(String hello, String world) {
return Hello.builder().hello(hello).world(world).build();
}
基于注解的控制器方式和使用Spring MVC Web时的方式类似,从函数参数获取请求值,返回的结果将通过默认的HttpMessageConverter进行转换(序列化成JSON数据)。
Header与Cookie
WebFlux下,获取Header与Cookie需要使用ServerHttpRequest
来获得,因为通常情况下使用WebFlux是基于Netty实现的,在这种情况下ServletHttpRequest
是没有加载的。
@GetMapping
public ApiResult findFromSession(ServerHttpRequest request) {
HttpCookie tokenCookie = request.getCookies().getFirst("token");
String tokenHeader = request.getHeaders().getFirst("token");
if (Objects.isNull(tokenCookie)) {
return ApiResult.error(StatusEnum.UNAUTHORIZED);
}
return ApiResult.ok(tokenCookie.getValue());
}
数据校验
请求数据的校验需要把@Valid
注解加到请求参数上,但与Spring 4及更早版本不同的地方是需要把请求参数使用Mono<T>
包起来。Bean校验的错误将作为Mono
的错误(Error
)被发送。
@PostMapping(path = "signup")
public Mono<ApiResult> signup(@Valid @RequestBody Mono<SignupDTO> mono) {
return mono.map(signupDTO ->
ApiResult.ok(credentialService.signup(signupDTO)))
.onErrorResume(httpComponent::justApiResult);
}
Reactive Core
Spring WebFlux的反应式核心有以下基本支持:
HttpHandler: HTTP服务处理,主要用于在不同的HTTP服务器上实现一个统一的请求/响应处理抽象;
WebHandler API: 是提供Web应用程序中常用的一组更广泛的功能,如:具有属性的用户会话、请求属性、表单处理、文件上传/下载等;
Filters: 过滤器,可控制处理流程;
Exceptions: 全局异常处理;
Codecs: HTTP请求/响应编码器,通过无阻塞I/O和反应流回压对更高级别的对象之间的字节进行序列化与反序列化;
Logging: 日志。
自定义编码器
@Overridepublic void configureHttpMessageCodecs(
ServerCodecConfigurer configurer) {
ServerCodecConfigurer.ServerDefaultCodecs defaultCodecs =
configurer.defaultCodecs();
defaultCodecs.jackson2JsonEncoder(
new Jackson2JsonEncoder(objectMapper));
defaultCodecs.jackson2JsonDecoder(
new Jackson2JsonDecoder(objectMapper));
}
小结
Spring开始已经拥抱反应式编程,本文通过一些简单的示例来演示了Spring 5引入的WebFlux,也算缓缓打开了反应式(Reactive)编程的大门。
完整的代码在Github上可以访问:https://github.com/yangbajing/spring-reactive-sample
以上是关于反应式的Spring 5的主要内容,如果未能解决你的问题,请参考以下文章
Spring 5 之 WebFlux 开发反应式 Web 应用
技术使用 Spring 5 的 WebFlux 开发反应式 Web 应用
使用 Spring 5 的反应式 WebSockets - 如何获取初始消息