springMvc:异步请求

介绍

同步操作:

在这里插入图片描述

异步操作:
在这里插入图片描述

?spring web 异步操作的实现有很多种, 我只学了两种?Callable 和DeferredResult

  • Callable : 在程序内部处理
  • DeferredResult: 需要处理DeferredResult

案例

Callable<?>使用

  @ResponseBody
    @RequestMapping("/async01")
    public Callable<String> async01() {
        System.out.println("主线程开始..." + Thread.currentThread() + "==>" + System.currentTimeMillis());

        Callable<String> callable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("副线程开始..." + Thread.currentThread() + "==>" + System.currentTimeMillis());
                Thread.sleep(2000);
                System.out.println("副线程开始..." + Thread.currentThread() + "==>" + System.currentTimeMillis());
                return "Callable<String> async01()";
            }
        };

        System.out.println("主线程结束..." + Thread.currentThread() + "==>" + System.currentTimeMillis());
        return callable;
    }

DeferredResult<?>使用

自定义DeFerredResultQueue

定义存储异步处理数据的队列

public class DeferredResultQueue {
	
	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();
	}

}

Controller

    @ResponseBody
    @RequestMapping("/createOrder")
    public DeferredResult<Object> createOrder() {
        DeferredResult<Object> deferredResult = new DeferredResult<>((long) 10000, "create fail...");

        DeferredResultQueue.save(deferredResult);

        return deferredResult;
    }


    @ResponseBody
    @RequestMapping("/create")
    public String create() {
        //创建订单
        String order = UUID.randomUUID().toString();
        DeferredResult<Object> deferredResult = DeferredResultQueue.get();
        deferredResult.setResult(order);
        return "success===>" + order;
    }

总结

Callable

- 1)  spring异步处理,先将Callable提交到TaskExecutor 使用一个隔离的线程进行执行
- 2)  DispatcherServlet和所有的Filter退出web容器的线程,但是response 保持打开状态
- 3)Callable 返回结果,SpringMvc 将请求重新派发给容器,恢复之前的处理
- 4)根据Callable返回的结果。 SpringMvc 继续进行试图渲染流程等

流程如下:

preHandle.../springmvc-annotation/async01 主线程开始...Thread[http-bio-8081-exec-3,5,main]==>1513932494700 主线程结束...Thread[http-bio-8081-exec-3,5,main]==>1513932494700 =========DispatcherServlet及所有的Filter退出线程============================

================等待Callable执行========== 副线程开始...Thread[MvcAsync1,5,main]==>1513932494707 副线程开始...Thread[MvcAsync1,5,main]==>1513932496708 ================Callable执行完成==========

================再次收到之前重发过来的请求======== preHandle.../springmvc-annotation/async01 postHandle...(Callable的之前的返回值就是目标方法的返回值) afterCompletion...

异步的拦截器: 1)、原生API的AsyncListener 2)、SpringMVC:实现AsyncHandlerInterceptor;

DeferredResult

执行流程(与Callable一致,不做翻译了,直接看英文吧?)

The controller returns a DeferredResult and saves it in some in-memory queue or list where it can be accessed.

Spring MVC calls request.startAsync().

Meanwhile, the DispatcherServlet and all configured filters exit the request processing thread, but the response remains open.

The application sets the DeferredResult from some thread, and Spring MVC dispatches the request back to the Servlet container.

The DispatcherServlet is invoked again, and processing resumes with the asynchronously produced return value.


参考

spring web Mvc 官方doc

源码地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值