Spring 3.2 Asynchronous Request Processing
In this section, you will learn about Asynchronous Request Processing in Spring MVC 3.2.
Before understanding asynchronous request processing, you must be familiar with Servlet 3 async processing feature.
Servlet 3 async processing
Given below the sequence of events of Servlet 3 async processing :
- By calling request.startAsync(), you can put ServletRequest
in asynchronous mode. Due to this , Servlet and any Filters exits but
response still open , permitting other thread to complete the processing.
- The request.startAsync() returns AsynContext which can
be utilize later to control the further processing. For example,
dispatch() method can be utilized to dispatch the request back to the
Servlet container.
- The current DispatcherType, provided by the ServletRequest,
can be utilized to differentiate when a Servlet / a Filter is processing the
initial request processing thread and when it is processing in an
asynchronous dispatch.
Asynchronous Request Processing
Spring 3.2 asynchronous request processing is based on Servlet 3 based asynchronous request processing. Spring 3.2 asynchronous request processing returns java.util.concurrent.Callable and DeferredResult instead of returning a value and bring out value from a separate thread.
When a application requires to return value asynchronously within a thread handled by Spring MVC, a java.util.concurrent.Callable is returned. Given below the example of a controller method returning Callable :
@RequestMapping(method=RequestMethod.POST) public Callable<String> UploadFile(final MultipartFile file) { return new Callable<String>() { public Object call() throws Exception { // ... return "anyView"; } }; }
When a application requires to return value asynchronously from a thread of
its own selection, a DeferredResult can be returned.
Given below the example of a controller method returning DeferredResult
:
@RequestMapping("/statements") @ResponseBody public DeferredResult<String> statements() { DeferredResult<String> defResult = new DeferredResult<String>(); // Save the defResult in memory return defResult; } // In some other thread... defResult.setResult(data);
Given below the sequence for Asynchronous Request Processing with Callable :
- First, a Callable is returned by the Controller.
- Asynchronous processing starts by the Spring MVC and also for processing
in a separate thread, it submits the Callable to a TaskExecutor.
- The response stays open in spite of the DispatcherServlet and
all Filter's exit.
- The result is created by the Callable and request is dispatch back to
the Servlet container by the Spring MVC.
- The DispatcherServlet called once again and processing restarts
with the asynchronously created result from the Callable.
Given below the sequence for Asynchronous Request Processing with a DeferredResult :
- First, a DeferredResult is returned by the Controller and it is
saved in memory fro further access.
- Asynchronous processing starts by the Spring MVC .
- The response stays open in spite of the DispatcherServlet and
all Filter's exit.
- From some thread, the application sets the DeferredResult and request is
dispatch back to the Servlet container by the Spring MVC.
- The DispatcherServlet called once again and processing restarts with the
asynchronously created result from the Callable.