010 异步处理Rest服务
一:任务
1.任务
使用Runnable异步处理Rest服务
使用DefaultResult异步处理Rest服务
异步处理的配置
2.原理图说明

二:Callable进行异步处理
1.程序
新建一个anysc的包
package com.cao.web.async; import java.util.concurrent.Callable; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
public class AsyncController {
private Logger logger=LoggerFactory.getLogger(getClass()); @RequestMapping("/order")
public Callable<String> order() throws Exception {
logger.info("主线程开始");
//业务逻辑放在副线程中
Callable<String> result=new Callable<String>() { @Override
public String call() throws Exception {
logger.info("副线程开始");
Thread.sleep(5000);
logger.info("副线程返回");
return "success";
} }; logger.info("主线程返回"); return result;
} }
2.效果
重点关注时间

三:使用DeferredResult
1.问题
方式一是有问题的,因为副线程是需要主线程调用起来的。
是写在主线程中的。
有些场景是不合适的。
线程间使用DeferredResult沟通起来。
2.场景如下:

3.程序
程序太多,有点复杂
控制器
package com.cao.web.async; import java.util.concurrent.Callable; import org.apache.commons.lang.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult; @RestController
public class AsyncController {
private Logger logger=LoggerFactory.getLogger(getClass());
@Autowired
private Queue queue; @Autowired
private DeferredResultHolder deferredResultHolder; /**
* 主要是验证Callable
* @return
* @throws Exception
*/
@RequestMapping("/order")
public Callable<String> order() throws Exception {
logger.info("主线程开始");
//业务逻辑放在副线程中
Callable<String> result=new Callable<String>() { @Override
public String call() throws Exception {
logger.info("副线程开始");
Thread.sleep(5000);
logger.info("副线程返回");
return "success";
} }; logger.info("主线程返回"); return result;
}
/**
* 主要是验证
* @return
* @throws Exception
*/
@RequestMapping("/newOrder")
public DeferredResult<String> newOrder() throws Exception {
logger.info("主线程开始");
//
String oderNumber=RandomStringUtils.randomNumeric(8);
queue.setPlaceOrder(oderNumber);
DeferredResult<String> result=new DeferredResult<>();
deferredResultHolder.getMap().put(oderNumber, result);
logger.info("主线程返回"); return result;
} }
queue.java
package com.cao.web.async; import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; @Component
public class Queue {
private String placeOrder;
private String completeOrder; private Logger logger=LoggerFactory.getLogger(getClass()); public String getPlaceOrder() {
return placeOrder;
}
public void setPlaceOrder(String placeOrder) throws Exception {
new Thread(() -> {
logger.info("接到下单请求");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 表示处理完成,应用2将结果返回给了completeOrder
this.completeOrder = placeOrder;
logger.info("下单请求处理完毕" + placeOrder);
} ).start(); }
public String getCompleteOrder() {
return completeOrder;
}
public void setCompleteOrder(String completeOrder) {
this.completeOrder = completeOrder;
} }
deferredResultHolder.java
package com.cao.web.async; import java.util.HashMap;
import java.util.Map; import org.springframework.stereotype.Component;
import org.springframework.web.context.request.async.DeferredResult; @Component
public class DeferredResultHolder {
//一个是订单号,一个是订单号的处理结果
private Map<String,DeferredResult<String>> map=new HashMap<>();
public Map<String,DeferredResult<String>> getMap(){
return map;
}
public void setMap(Map<String,DeferredResult<String>> map) {
this.map=map;
}
}
QueueListener.java
package com.cao.web.async; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.log; import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component; @Component
public class QueueListener implements ApplicationListener<ContextRefreshedEvent>{
@Autowired
private Queue queue; @Autowired
private DeferredResultHolder deferredResultHolder; private Logger logger=LoggerFactory.getLogger(getClass()); @Override
public void onApplicationEvent(ContextRefreshedEvent event) {
new Thread(() -> {
while (true) {
if (StringUtils.isNotBlank(queue.getCompleteOrder())) {
String orderNumber = queue.getCompleteOrder();
logger.info("返回订单处理结果" + orderNumber);
deferredResultHolder.getMap().get(orderNumber).setResult("place order success");
queue.setCompleteOrder(null);
} else {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}).start(); } }
4.效果
前端效果

控制台效果

三:异步线程的配置
1.说明
对于拦截器,与同步的拦截器不一样,仍然需要配置、
2.主要配置

010 异步处理Rest服务的更多相关文章
- WPF异步调用WCF服务
wpf调用wcf时,第一次访问总耗时到达几秒,影响界面的用户体验,因此在wpf加载界面和加载数据时采用异步加载,即异步访问wcf服务, 由于是否采用异步加载和服务端无关,仅仅由客户端自己根据需要来选择 ...
- Java笔记(十七) 异步任务执行服务
异步任务执行服务 一.基本原理和概念 一)基本接口 1)Runnable和Callable:表示要执行的异步任务. 2)Executor和ExecutorService:表示执行服务. 3)Futur ...
- 使用kendynet构建异步redis访问服务
使用kendynet构建异步redis访问服务 最近开始在kendynet上开发手游服务端,游戏类型是生存挑战类的,要存储的数据结构和类型都比较简单,于是选择了用redis做存储,数据类型使用stri ...
- Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务、WCF消息头添加安全验证Token
原文:Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务.WCF消息头添加安全验证Token 为什么选择wcf? 因为好像wcf和wpf就是哥俩,,, 为什么选择异步 ...
- mvc路由引起异步调用web服务的问题
从一篇blog得知使用脚本可以异步调用Web服务,觉得很新鲜,因为自己很少用到Web服务,所以决定写一写看看什么效果. 首先在UI项目(我使用的是MVC4.0)里创建一个Web服务. 添加Web服务后 ...
- Silverlight中异步调用WCF服务,传入回调函数
以前学的ASP.NET,调用的都是同步方法,同步方法的好处就是,一步一步走,完成这步才会走下一步.然而,WCF使用的都是异步方法,调用之后不管有没有获得结果就直接往下走,最可恶的是异步函数都是Void ...
- 多线程编程学习笔记——异步调用WCF服务
接上文 多线程编程学习笔记——使用异步IO 接上文 多线程编程学习笔记——编写一个异步的HTTP服务器和客户端 接上文 多线程编程学习笔记——异步操作数据库 本示例描述了如何创建一个WCF服务,并宿主 ...
- Java编程的逻辑 (77) - 异步任务执行服务
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...
- 25.C# 异步调用Web服务
1.创建Web服务 1.1VS新建ASP.Net空Web应用程序 1.2添加Web服务新建项 1.3添加GetWeather方法和相关类 using System; using System.Coll ...
随机推荐
- 如何将本地项目上传到Github
看了这篇文章觉得写的很详细很适合初学者 提供给大家参考下. http://blog.csdn.net/zamamiro/article/details/70172900 注意如果第二次git pus ...
- f11 全屏
function fullScreen() { var el = document.documentElement; var rfs = el.requestFullScreen || el.webk ...
- Confluence 6 协同编辑问题解决
协同编辑是 Synchrony 提供的,用于在编辑的时候实时同步.在一般的情况下,这个进程是不需要 Confluence 的管理员进行手动管理的. 这个页面将会帮助你 Confluence 安装实例中 ...
- pytorch 参数初始化
https://blog.csdn.net/daydayjump/article/details/80899029
- 【mysql】datetime时间比较
如下,比较的日期用指定格式写出就可以了.不需要日期函数. SELECT * FROM table_a WHERE write_date > "2017-07-17 00:00:00&q ...
- Python实战一
要求:用户输入用户名和密码错误三次,就对该用户进行锁定,不让其进行登录. def match(name,pwd): '''匹配用户输入的信息,进行判断''' falg = True while fal ...
- MYSQL之 error while loading shared libraries: libtinfo.so.5: cannot open shared objectfile: No such f
环境:ubuntu18 登陆MYSQL时遇到错误:mysql: error while loading shared libraries: libtinfo.so.5: cannot open sha ...
- Burp Scanner Report
1.使用application web 漏洞平台,除此之外还有一款类似的工具 叫做mulidata,其实mulidata功能更好一点. 2.配置之前的问题处理 安装之前要确认 自己之前是否安装过 Ap ...
- js变量前的+是什么意思
js变量前的+是什么意思 if (+value >= distance) {} 这个+什么意思 可以理解为 Number(value) 会将其按照Number函数的规则转换为数值或者NaN, ...
- Vue-CLI 3.x 设置反向代理
最近在项目中使用了Vue CLI 3.0版本,项目中需要设置反向代理解决跨域问题,下面记录一下设置过程. 新建配置文件 (vue-cli3.x 官网的配置文档 https://cli.vuejs.or ...