DeferredResult上的小演示应用程序在春天

时间:2015-09-24 05:24:24

标签: java spring-mvc

嗨,我只需要在Spring MVC中使用DeferredResult上的一个应用程序来清除它的工作。

2 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

了解DeferredResult的概念会更容易: 您的控制器最终是由servlet容器(就此而言,假设服务器容器为Tomcat)工作线程执行的功能。您的服务流以Tomcat开头,以Tomcat结束。 Tomcat从客户端获取请求,保留连接,并最终向客户端返回响应。您的代码(控制器或servlet)在中间。

考虑以下流程:

  1. Tomcat获取客户端请求。
  2. Tomcat执行您的控制器。
  3. 释放Tomcat线程,但保持客户端连接(不返回响应)并在其他线程上运行繁重的处理。
  4. 完成繁重的处理后,请更新Tomcat的响应并将其返回给客户端(通过Tomcat)。

由于Servlet(您的代码)和Servlet容器(Tomcat)是不同的实体,因此要允许此流程(释放tomcat线程,但保持客户端连接),我们需要在their contract中提供此支持,包javax.servlet,在Servlet 3.0中引入。当控制器的返回值为DeferredResult(BTW,也为Callable)时,Spring MVC使用此新的Servlet 3.0功能。 DeferredResult是由Spring设计的类,它允许在Spring MVC中为异步请求处理提供更多选项(我将描述),并且该类仅保存结果(如其名称所示),因此它意味着您需要某种线程将运行您的异步代码。使用DeferredResult作为控制器的返回值,您会得到什么? DeferredResult具有内置的回调,例如onErroronTimeoutonCompletion。它使错误处理变得非常容易。

Here,您可以找到我创建的简单工作示例。

来自github示例的主要部分:

@RestController
public class DeferredResultController {
    static ExecutorService threadPool = getThreadPool();
    private Request request = new Request();

    @RequestMapping(value="/deferredResultHelloWorld/{name}", method = RequestMethod.GET)
    public DeferredResult<String> search(@PathVariable("name") String name) {
        DeferredResult<String> deferredResult = new DeferredResult<>();
        threadPool.submit(() -> deferredResult.setResult(request.runSleepOnOtherService(name)));
        return deferredResult;
    }
}
相关问题