Spring MVC现在已经支持异步请求处理流程了一段时间,该支持内部利用了Tomcat / Jetty等容器的Servlet 3异步支持。

Spring Web Async支持

考虑一下需要花一点时间处理的服务呼叫,该服务呼叫具有延迟:

public CompletableFuture<Message> getAMessageFuture() {return CompletableFuture.supplyAsync(() -> {logger.info("Start: Executing slow task in Service 1");Util.delay(1000);logger.info("End: Executing slow task in Service 1");return new Message("data 1");}, futureExecutor);
}

如果要在用户请求流中调用此服务,则传统的阻塞控制器流将如下所示:

@RequestMapping("/getAMessageFutureBlocking")
public Message getAMessageFutureBlocking() throws Exception {return service1.getAMessageFuture().get();
}

更好的方法是使用Spring异步支持,以便在CompletableFuture可用时将结果返回给用户,这样就不会占用容器线程了:

@RequestMapping("/getAMessageFutureAsync")
public DeferredResult<Message> getAMessageFutureAsync() {DeferredResult<Message> deffered = new DeferredResult<>(90000);CompletableFuture<Message> f = this.service1.getAMessageFuture();f.whenComplete((res, ex) -> {if (ex != null) {deffered.setErrorResult(ex);} else {deffered.setResult(res);}});return deffered;
}

在异步流中使用Observable

现在到本文的主题,最近我一直在使用Rx-java的出色的Observable类型作为我的服务返回类型,并希望确保Web层在处理从服务调用返回的Observable类型时也保持异步。

考虑现在修改的上述服务以返回一个Observable:

public Observable<Message> getAMessageObs() {return Observable.<Message>create(s -> {logger.info("Start: Executing slow task in Service 1");Util.delay(1000);s.onNext(new Message("data 1"));logger.info("End: Executing slow task in Service 1");s.onCompleted();}).subscribeOn(Schedulers.from(customObservableExecutor));
}

我可以通过在Web层结束阻塞调用来使返回Observable的所有好处无效,一个朴素的调用将是以下内容:

@RequestMapping("/getAMessageObsBlocking")
public Message getAMessageObsBlocking() {return service1.getAMessageObs().toBlocking().first();
}

为了使此流在Web层中异步,以下是处理此调用的更好方法,基本上是将Observable转换为Spring的DeferredResult类型:

@RequestMapping("/getAMessageObsAsync")
public DeferredResult<Message> getAMessageAsync() {Observable<Message> o = this.service1.getAMessageObs();DeferredResult<Message> deffered = new DeferredResult<>(90000);o.subscribe(m -> deffered.setResult(m), e -> deffered.setErrorResult(e));return deffered;
}

这将确保处理用户流的线程将在服务调用完成后立即返回,并且一旦可观察到的开始发出值,就将对用户响应进行反应性处理。

如果您有兴趣进一步探索, 这里是一个带有工作示例的github存储库:https://github.com/bijukunjummen/spring-web-observable。

参考文献:

Spring关于Web层中异步流的参考指南:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-async

NoBlogDefFound博客上无与伦比的Tomasz Nurkiewicz提供的有关Spring DeferredResult的更多详细信息 -http://www.nurkiewicz.com/2013/03/deferredresult-asynchronous-processing.html

翻译自: https://www.javacodegeeks.com/2015/03/using-rx-java-observable-in-a-spring-mvc-flow.html

在Spring MVC流中使用rx-java Observable相关推荐

  1. rx.observable_在Spring MVC流中使用rx-java Observable

    rx.observable Spring MVC现在已经支持异步请求处理流程了一段时间,该支持内部利用了Tomcat / Jetty等容器的Servlet 3异步支持. Spring Web Asyn ...

  2. observable_在Spring MVC流中使用rx-java Observable

    observable Spring MVC现在已经支持异步请求处理流程了一段时间,该支持内部利用了Tomcat / Jetty等容器的Servlet 3异步支持. Spring Web Async支持 ...

  3. java注解返回不同消息,Spring MVC Controller中的一个读入和返回都是JSON的方法如何获取javax.validation注解的异常信息...

    Spring MVC Controller中的一个读入和返回都是JSON的方法怎么获取javax.validation注解的错误信息? 本帖最后由 LonelyCoder2012 于 2014-03- ...

  4. Spring MVC环境中的文件上传功能实现

    在实际开发过程中,尤其是web项目开发,文件上传和下载的需求的功能非常场景,比如说用户头像.商品图片.邮件附件等等.其实文件上传下载的本质都是通过流的形式进行读写操作,而在开发中不同的框架都会对文件上 ...

  5. spring mvc项目中利用freemarker生成自定义标签

    2019独角兽企业重金招聘Python工程师标准>>> spring mvc项目中利用freemarker生成自定义标签 博客分类: java spring mvc +freemar ...

  6. Spring MVC框架中关于限制请求方式

    在Spring MVC框架中,@RequestMapping注解的主要作用是配置请求路径,除此以外,还可以配置请求方式,例如: @RequestMapping(value = "/add-n ...

  7. Spring MVC 应用中异常处理流程分析 : sendError() vs setStatus()

    sendError() Spring MVC应用处理某个请求时遇到异常的话,除非开发人员明确地指定使用setStatus(),否则都是面向sendError()的处理流程,总的来说该处理流程概括如下 ...

  8. 如何在Spring和Spring MVC项目中进行测试

    Spring框架概述 Spring大约包含了20个模块,这些模块组成了核心容器(Core Container).数据访问/集成(Data Access/Integration).Web.AOP(面向切 ...

  9. Http请求中Content-Type讲解以及在Spring MVC注解中produce和consumes配置详解

    转载自https://blog.csdn.net/shinebar/article/details/54408020 引言: 在Http请求中,我们每天都在使用Content-type来指定不同格式的 ...

最新文章

  1. CTabCtrl - 如何使用TabCtrl控件
  2. linux下crontab allow,Linux下crontab命令的用法
  3. Vim 4 常用插件
  4. Camel 2.11 –具有URL重写功能的HTTP代理路由
  5. 语义分割之图像经镜像、翻转、裁剪后像素点的位置映射
  6. 论文笔记_S2D.20_2017-ICCV-从单张RGB图像到精确尺度深度图评估的一种双支网络
  7. 【图像隐写】基于matlab GUI DWT+DCT+SVD数字水印嵌入提取攻击(带面板)【含Matlab源码 1664期】
  8. iOS app 启动 crash XCode 11 NSPOSIXErrorDomain Code=2 “No such file or directory“
  9. Redis 客户端工具
  10. ajax加载图片使用,Lightbox–Ajax加载下图片灯箱的使用
  11. mysql 周平均值_SQL语句: 按周、月统计总值 和 平均值
  12. laravel8+jwt+邮箱注册验证
  13. 2019年京东面试题-洗咖啡杯问题【贪心和动态规划】
  14. 一个最简单的自定义锁屏应用实现
  15. ARM学习笔记:HC-SR501人体红外传感器
  16. Driver class 'org.gjt.mm.mysql.Driver' could not be found, make sure the 'MySQL' driver (jar file)
  17. Normalized Mutual information
  18. 数据存储计量单位换算
  19. 一键装机linux_教你如何使用u盘安装Linux系统
  20. 2018-2019-2 20175227张雪莹 《Java程序设计》 实验一 Java开发环境的熟悉

热门文章

  1. 使用ueditor实现多图片上传案例——Service层(IShoppingService)
  2. java实现人脸识别源码【含测试效果图】——Dao层(IBaseDaoUtil)
  3. 服务器windows系统如何登陆,如何登陆windows云服务器
  4. win7精简_低配电脑的福音:这款小众系统10GB+极限精简+不卡顿,比Win7还快!
  5. tomcat(10)安全性
  6. Vue 媒体处理(摄像头,截图,播放本地视频)
  7. spring http缓存_HTTP缓存与Spring示例
  8. activemq 性能测试_ActiveMQ性能测试
  9. java8根据某个id删选_Java 8可选
  10. jsp界面自动生成文件注释_实施注释界面