初识
从编程模型的角度来看,这种新功能貌似很简单。一个控制器方法能返回一个java.util.concurrent.Callable回调方法来异步的完成处理。Spring MVC将在TaskExecutor的帮助下在一个单独的线程中调用该回调方法。下面的代码是以前的写法:
// Before @RequestMapping(method=RequestMethod.POST) public String processUpload(final MultipartFile file) { // ... return "someView"; } // After @RequestMapping(method=RequestMethod.POST) public Callable<String> processUpload(final MultipartFile file) { return new Callable<String>() { public Object call() throws Exception { // ... return "someView"; } }; }一个控制器方法也能返回一个DeferredResult(Spring MVC 3.2中的新类型) ,来在一个Spring MVC不知道的线程中完成处理。例如,响应一个JMS消息或一个AMQP消息,一个Redis通知,等等。下面是另一种写法的代码:
@RequestMapping("/quotes") @ResponseBody public DeferredResult<String> quotes() { DeferredResult<String> deferredResult = new DeferredResult<String>(); // Add deferredResult to a Queue or a Map... return deferredResult; } // In some other thread... deferredResult.setResult(data); // Remove deferredResult from the Queue or Map上面的两个例子带来了很多问题,我们将在以后的文章中展开详细讨论。现在,我准备开始 围绕着这些新特性,介绍一些相关知识。
在另一些情况下,必须要返回处理结果,那么我们就需要把处理过程从Servlet容器中解耦出来,否则我们将耗光线程池。Servlet 3提供了这种支持,Servlet (或者Spring MVC的控制器) 能够指示response在Servlet容器的线程退出之后保持开放状态。
要实现这种效果, Servlet 3 web应用可以调用request.startAsync(),然后在其他独立的线程中使用返回的AsyncContext来继续向response写入信息。同时,从客户端的角度来看,request仍然像任何其他的HTTP的request-response交互一样,只是耗费了更长的时间而已。下面是事件的顺序:
评论删除后,数据将无法恢复
评论(0)