【Spring 5】响应式Web框架前瞻

2,565 阅读4分钟

引子:被誉为“中国大数据第一人”的涂子沛先生在其成名作《数据之巅》里提到,摩尔定律、社交媒体、数据挖掘是大数据的三大成因。IBM的研究称,整个人类文明所获得的全部数据中,有90%是过去两年内产生的。在此背景下,包括NoSQL,Hadoop, Spark, Storm, Kylin在内的大批新技术应运而生。其中以RxJavaReactor为代表的响应式(Reactive)编程技术针对的就是经典的大数据4V定义(Volume,Variety,Velocity,Value)中的Velocity,即高并发问题,而在即将发布的Spring 5中,也引入了响应式编程的支持。在接下来的几周,我会围绕响应式编程分三期与你分享我的一些学习心得。作为第一篇,首先从Spring 5谈起。

1 响应式宣言

敏捷宣言一样,说起响应式编程,必先提到响应式宣言。

We want systems that are Responsive, Resilient, Elastic and Message Driven. We call these Reactive Systems. - The Reactive Manifesto

图片出处:The Reactive Manifesto

不知道是不是为了向敏捷宣言致敬,响应式宣言中也包含了4组关键词:

  • Responsive: 可响应的。要求系统尽可能做到在任何时候都能及时响应。
  • Resilient: 可恢复的。要求系统即使出错了,也能保持可响应性。
  • Elastic: 可伸缩的。要求系统在各种负载下都能保持可响应性。
  • Message Driven: 消息驱动的。要求系统通过异步消息连接各个组件。

可以看到,对于任何一个响应式系统,首先要保证的就是可响应性,否则就称不上是响应式系统。从这个意义上来说,动不动就蓝屏的Windows系统显然不是一个响应式系统。

PS: 如果你赞同响应式宣言,不妨到官网上留下的你电子签名,我的编号是18989,试试看能不能找到我。

2 Spring 5前瞻

作为Java世界首个响应式Web框架,Spring 5最大的亮点莫过于提供了完整的端到端响应式编程的支持。

图片出处:Spring Framework Reference Documentation

左侧是传统的基于Servlet的Spring Web MVC框架,右侧是5.0版本新引入的基于Reactive Streams的Spring WebFlux框架,从上到下依次是Router Functions,WebFlux,Reactive Streams三个新组件。

  • Router Functions: 对标@Controller,@RequestMapping等标准的Spring MVC注解,提供一套函数式风格的API,用于创建Router,Handler和Filter。
  • WebFlux: 核心组件,协调上下游各个组件提供响应式编程支持。
  • Reactive Streams: 一种支持背压(Backpressure)的异步数据流处理标准,主流实现有RxJava和Reactor,Spring WebFlux默认集成的是Reactor。

在Web容器的选择上,Spring WebFlux既支持像Tomcat,Jetty这样的的传统容器(前提是支持Servlet 3.1 Non-Blocking IO API),又支持像Netty,Undertow那样的异步容器。不管是何种容器,Spring WebFlux都会将其输入输出流适配成Flux<DataBuffer>格式,以便进行统一处理。

值得一提的是,除了新的Router Functions接口,Spring WebFlux同时支持使用老的Spring MVC注解声明Reactive Controller。和传统的MVC Controller不同,Reactive Controller操作的是非阻塞的ServerHttpRequest和ServerHttpResponse,而不再是Spring MVC里的HttpServletRequest和HttpServletResponse。

下面是我GitHub上的示例工程里的一个例子

@RestController
public class RestaurantController {

    private final RestaurantRepository restaurantRepository;

    private final ReactiveMongoTemplate reactiveMongoTemplate;

    public RestaurantController(RestaurantRepository restaurantRepository, ReactiveMongoTemplate reactiveMongoTemplate) {
        this.restaurantRepository = restaurantRepository;
        this.reactiveMongoTemplate = reactiveMongoTemplate;
    }

    @GetMapping("/reactive/restaurants")
    public Flux<Restaurant> findAll() {
        return restaurantRepository.findAll();
    }

    @GetMapping("/reactive/restaurants/{id}")
    public Mono<Restaurant> get(@PathVariable String id) {
        return restaurantRepository.findById(id);
    }

    @PostMapping("/reactive/restaurants")
    public Flux<Restaurant> create(@RequestBody Restaurant[] restaurants) {
        return Flux.just(restaurants)
                .log()
                .flatMap(r -> Mono.just(r).subscribeOn(Schedulers.parallel()), 10)
                .flatMap(reactiveMongoTemplate::insert);
    }
}

3 小结

除了响应式编程支持,Spring 5还包括了很多Java程序员期待已久的特性,包括JDK 9,Junit 5,Servlet 4以及HTTP/2支持。目前Spring 5的最新版本是RC1,而Spring Boot也刚刚发布了2.0.0 M1版本。根据Spring官方博客,Spring 5将在JDK 9 GA之后随即发布,也就是今年的7月底前后。

以上就是我对Spring 5中有关响应式编程支持的一些简单介绍,欢迎你到我的留言板分享,和大家一起过过招。下一篇我将聊一下我对响应式编程的一些理解,敬请期待。

4 参考