在spring mvc3.2及以上版本增長了對請求的異步處理,是在servlet3的基礎上進行封裝的。html
一、修改web.xmljava
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="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"> ... </web-app>
1.一、聲明version="3.0",聲明web-app_3_0.xsdweb
1.二、爲servlet或者filter設置啓用異步支持:<async-supported>true</async-supported>,修改WEB應用的web.xmlspring
<!-- spring mvc --> <servlet> <servlet-name>SpringMvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>...</param-value> </init-param> <load-on-startup>1</load-on-startup> <async-supported>true</async-supported> </servlet>
二、使controller類支持async服務器
2.一、返回java.util.concurrent.Callable來完成異步處理mvc
package org.springframework.samples.mvc.async; import java.util.concurrent.Callable; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.context.request.async.WebAsyncTask; @Controller @RequestMapping("/async/callable") public class CallableController { @RequestMapping("/response-body") public @ResponseBody Callable<String> callable() { return new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(2000); return "Callable result"; } }; } @RequestMapping("/view") public Callable<String> callableWithView(final Model model) { return new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(2000); model.addAttribute("foo", "bar"); model.addAttribute("fruit", "apple"); return "views/html"; } }; } @RequestMapping("/exception") public @ResponseBody Callable<String> callableWithException( final @RequestParam(required=false, defaultValue="true") boolean handled) { return new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(2000); if (handled) { // see handleException method further below throw new IllegalStateException("Callable error"); } else { throw new IllegalArgumentException("Callable error"); } } }; } @RequestMapping("/custom-timeout-handling") public @ResponseBody WebAsyncTask<String> callableWithCustomTimeoutHandling() { Callable<String> callable = new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(2000); return "Callable result"; } }; return new WebAsyncTask<String>(1000, callable); } @ExceptionHandler @ResponseBody public String handleException(IllegalStateException ex) { return "Handled exception: " + ex.getMessage(); } }
2.二、在異步處理完成時返回org.springframework.web.context.request.async.DeferredResult其餘線程,例如一個JMS或一個AMQP消息,Redis通知等等:app
@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
三、spring配置文件的修改異步
spring mvc的dtd的聲明必須大於等於3.2async
<mvc:annotation-driven> <!-- 可不設置,使用默認的超時時間 --> <mvc:async-support default-timeout="3000"/> </mvc:annotation-driven>
實際使用示例:ide
function deferred(){ $.get('quotes.htm',function(data){ console.log(data); deferred();//每次請求完成,再發一次請求,避免客戶端定時刷新來獲取數據 }); }
這麼作的好處避免web server的鏈接池被長期佔用而引發性能問題,調用後生成一個非web的服務線程來處理,增長web服務器的吞吐量~~
能夠看下這個blog,還不錯:http://wiselyman.iteye.com/blog/2215852