Starting with spring3.2, support for SERVLET3 asynchronous requests, which is good for processing time-consuming requests such as slow database queries, does not quickly consume the servlet's thread pool, affecting extensibility.
Let's first look at how the servlet handles asynchronous operations:
- by calling Request.startasync (), the ServletRequest becomes an asynchronous pattern. The main effect is that the servlet, filter exits, but response remains open to complete the request processing.
- Calling Request.startasync () returns the Asynccontext instance to further control asynchronous processing. For example, it provides a dispatch method that can be called from the application thread to distribute the request back to the servlet container. Asynchronous scheduling and forward are similar, but asynchronous scheduling is generated by the application thread to the servlet container thread, while the forward is occurring concurrently on the same servlet container thread.
- ServletRequest provides the current dispatchertype, which can be used to distinguish whether the initial request thread being processed is a servlet or filter in an asynchronous schedule.
Then take a look at how callable handles asynchronous operations:
- Controller returns a callable instance;
- Spring MVC begins to process asynchronously and commits a callable instance to taskexecutor processing in a separate thread;
- Dispatcherservlet and all filter exits the request thread but response save opens;
- Callable returns the result, Spring MVC distributes the request back to the servlet container;
- Dispatcherservlet re-invokes and continues processing the results returned asynchronously from the callable instance.
Now let's take a look at how the code is implemented.
1, Pom.xml
<Dependency> <groupId>Javax.servlet</groupId> <Artifactid>Javax.servlet-api</Artifactid> <version>3.1.0</version></Dependency> <Dependency> <groupId>Org.springframework</groupId> <Artifactid>Spring-context-support</Artifactid> <version>3.2.13.RELEASE</version></Dependency> <Dependency> <groupId>Org.springframework</groupId> <Artifactid>Spring-webmvc</Artifactid> <version>3.2.13.RELEASE</version></Dependency>
2, Applicationcontext-mvc.xml
<?XML version= "1.0" encoding= "UTF-8"?><Beansxmlns= "Http://www.springframework.org/schema/beans"Xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance"Xmlns:context= "Http://www.springframework.org/schema/context"Xmlns:mvc= "Http://www.springframework.org/schema/mvc"Xmlns:task= "Http://www.springframework.org/schema/task"xsi:schemalocation= "Http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/MVC http://www.springframework.org/schema/mvc/spring-mvc.xsd/HTTP Www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd/HTTP Www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "> <Context:component-scanBase-package= "Com.test"/> <Mvc:annotation-driven> <!--Configuring the time-out period - <Mvc:async-supportDefault-timeout= " the"> <!--callable or Deferred-result interceptors can be configured here - </Mvc:async-support> </Mvc:annotation-driven></Beans>
3. Web. XML, when there are many filter, filter also must add asynchronous support
<?XML version= "1.0" encoding= "UTF-8"?><Web-appxmlns= "Http://java.sun.com/xml/ns/javaee"Xmlns:xsi= "Http://www.w3.org/2001/XMLSchema-instance"xsi:schemalocation= "Http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"version= "3.0"> <Filter> <Filter-name>Characterencodingfilter</Filter-name> <Filter-class>Org.springframework.web.filter.CharacterEncodingFilter</Filter-class> <async-supported>True</async-supported> <Init-param> <Param-name>Encoding</Param-name> <Param-value>UTF-8</Param-value> </Init-param> <Init-param> <Param-name>Forceencoding</Param-name> <Param-value>True</Param-value> </Init-param> </Filter> <filter-mapping> <Filter-name>Characterencodingfilter</Filter-name> <Url-pattern>/*</Url-pattern> </filter-mapping> <servlet> <Servlet-name>Dispatcherservlet</Servlet-name> <Servlet-class>Org.springframework.web.servlet.DispatcherServlet</Servlet-class> <Init-param> <Param-name>Contextconfiglocation</Param-name> <Param-value>Classpath*:applicationcontext-mvc.xml</Param-value> </Init-param> <Load-on-startup>1</Load-on-startup> <async-supported>True</async-supported> </servlet> <servlet-mapping> <Servlet-name>Dispatcherservlet</Servlet-name> <Url-pattern>/</Url-pattern> </servlet-mapping></Web-app>
Web. XML needs to declare web-app_3_0.xsd and version= "3.0″, enabling asynchronous support <async-supported>true</ Async-supported>
4, Callablecontroller.java
PackageCom.test.controller;ImportOrg.springframework.stereotype.Controller;ImportOrg.springframework.ui.ModelMap;Importorg.springframework.web.bind.annotation.RequestMapping;ImportOrg.springframework.web.bind.annotation.RequestMethod;ImportOrg.springframework.web.servlet.ModelAndView;Importjava.util.concurrent.Callable;/*** Spring Implementation: * 1, the task is submitted to executor asynchronous execution*/@Controller Public classCallablecontroller {@RequestMapping (value= "/callable1", method =requestmethod.get) PublicCallable<string> Callable1 (FinalModelmap Modelmap) { return NewCallable<string>() { PublicString Call ()throwsException {thread.sleep (2 * 1000L);//pause for 2 secondsreturn"Hello callable"; } }; } }
5,tomcat section, if Tomcat is deployed with session paging cache plug-in, you also add asynchronous support where the plug-in is configured:
<!--Redis Cache Support--
<ValveClassName= "Com.radiadesign.catalina.session.RedisSessionHandlerValve"asyncsupported= "true" /> <ManagerClassName= "Com.radiadesign.catalina.session.RedisSessionManager"Host= "localhost"Port= "6379"Database= "0"Maxinactiveinterval= "$" />
6, start the service, test:
Http://localhost:8088/test/callable1
7, RSP:
Hello callable
Spring MVC Asynchronous Test