Spring MVC 異步測試

從spring3.2開始,支持servlet3的異步請求,這對於處理耗時的請求如緩慢的數據庫查詢是很是有好處的,不至於很快的耗光servlet的線程池,影響可擴展性。
讓咱們先來了解一下servlet是怎麼處理異步操做的:java

  1. 經過調用request.startAsync(),ServletRequest就變成異步模式。主要的影響是Servlet、Filter會退出,可是Response保持打開用來完成請求處理。
  2. 調用request.startAsync()返回AsyncContext實例,可進一步控制異步處理。例如,它提供dispatch方法,可 以從應用線程調用以分發請求回Servlet容器。異步調度和forward的方式是類似的,可是異步調度是由應用線程到Servlet容器線程產生的, 而forward的方式是同時發生在相同的Servlet容器線程。
  3. ServletRequest提供當前的DispatcherType,它能夠用來在異步調度中區分正在處理的初始請求線程是Servlet仍是Filter。

接着來看一下callable是怎麼處理異步操做的:web

  1. Controller返回一個Callable實例;
  2. Spring MVC開始異步處理並在一個單獨的線程中,提交Callable實例給TaskExecutor處理;
  3. DispatcherServlet和全部的Filter退出請求線程可是response保存打開;
  4. Callable返回結果,Spring MVC分發請求回Servlet容器;
  5. DispatcherServlet從新調用並繼續處理從Callable實例中異步返回的結果。

如今來看一下代碼是怎麼實現的redis

一、pom.xmlspring

<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>

 

 

二、applicationContext-mvc.xml數據庫

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="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-scan base-package="com.test"/>
 
    <mvc:annotation-driven>
        <!-- 配置超時時間 -->
        <mvc:async-support default-timeout="3000">
            <!-- 這裏能夠配置callable或者deferred-result攔截器 -->
        </mvc:async-support>
    </mvc:annotation-driven>
</beans>

三、web.xml  , 當有 不少 filter 時,filter 也必定要添加異步支持api

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app
        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"
        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須要聲明web-app_3_0.xsdversion=」3.0″,啓用異步支持<async-supported>true</async-supported>
四、CallableController.javaspring-mvc

package com.test.controller;
 
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
 
import java.util.concurrent.Callable;
 
/**
 * spring實現方式:
 *  一、把任務提交給Executor異步執行
 */
@Controller
public class CallableController {
 
    @RequestMapping(value = "/callable1", method = RequestMethod.GET)
    public Callable<String> callable1(final ModelMap modelMap) {
        return new Callable<String>() {
            public String call() throws Exception {
                Thread.sleep(2 * 1000L); //暫停2秒return "hello callable";
            }
        };
    } 
}

 

5,tomcat 部分,若是 tomcat 部署有 session  分頁式緩存插件,則在插件配置的地方,也要添加異步支持: 緩存

  

    <!-- redis 緩存支持  --> 
<Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve" asyncSupported="true" /> <Manager className="com.radiadesign.catalina.session.RedisSessionManager" host="localhost" port="6379" database="0" maxInactiveInterval="60" />

 

6, 啓動服務,測試:tomcat

 http://localhost:8088/test/callable1session

 

7, rsp:

    hello callable

相關文章
相關標籤/搜索