spring mvc 异步 DeferredResult

当一个请求到达API接口,如果该API接口的return返回值是DeferredResult,在没有超时或者DeferredResult对象设置setResult时,接口不会返回,但是Servlet容器线程会结束,DeferredResult另起线程来进行结果处理,并setResult,如此以来这个请求不会占用服务连接池太久,如果超时或设置setResult,接口会立即返回。

使用DeferredResult的流程:

  1. 浏览器发起异步请求
  2. 请求到达服务端被挂起
  3. 向浏览器进行响应,分为两种情况:
    3.1 调用DeferredResult.setResult(),请求被唤醒,返回结果
    3.2 超时,返回一个你设定的结果
  4. 浏览得到响应,再次重复1,处理此次响应结果
@Controller
public class AsycController {
    @RequestMapping("create")
    @ResponseBody
    public DeferredResult<Object> create(){

        DeferredResult<Object> deferredResult=new DeferredResult<Object>((long)5000,"create fail");
        DeferredQueue.save(deferredResult);
        return deferredResult;

    }

    @RequestMapping("get")
    @ResponseBody
    public String get(){
        String orderid= UUID.randomUUID().toString();
        DeferredResult<Object> deferredResult=DeferredQueue.get();
        deferredResult.setResult(orderid);
        return "get orderid="+orderid;
    }
}
public class DeferredQueue {
    private static Queue<DeferredResult<Object>> queue=new ConcurrentLinkedQueue<DeferredResult<Object>>();

    public static void save(DeferredResult<Object> deferredResult){
        queue.add(deferredResult);
    }

    public static DeferredResult<Object> get(){
       return queue.poll();
    }
}

 

 

 请求create 后 5秒内   请求 get 则异步结束 返回 结果 

 

posted @ 2019-11-26 15:37  MartinEDM  阅读(561)  评论(0编辑  收藏  举报