SpringMVC与Servlet3.0整合 - 异步处理

Servlet3.0提供了异步处理支持,SpringMVC对其进行了封装,可以通过两种方式进行异步处理。

【1】Callable

官方文档地址:

https://docs.spring.io/spring/docs/5.0.5.RELEASE/spring-framework-reference/web.html#mvc-ann-async-callable

这里写图片描述


其原理如下:

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


代码示例如下:

    @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;
    }

测试如下:

这里写图片描述


【2】DeferredResult

一旦启用了异步请求处理功能 ,控制器就可以将返回值包装在DeferredResult,控制器可以从不同的线程异步产生返回值。

优点就是可以实现两个完全不相干的线程间的通信。

首先创建一个存储DeferredResult的实例

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();
    }

}

两个请求方法如下:

    @ResponseBody
    @RequestMapping("/createOrder")
    public DeferredResult<Object> createOrder(){
        DeferredResult<Object> deferredResult = new DeferredResult<>((long)3000, "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;
    }

首先http://localhost:8080/springmvc-annotation/createOrder请求获取order,有结果返回,超出等待时间返回创建失败。

http://localhost:8080/springmvc-annotation/create请求创建order,并给deferredResult赋值。

猜你喜欢

转载自blog.csdn.net/j080624/article/details/80021557