使用Callable的和流程
1、控制器返回一个Callable。
2、Spring 异步处理,将callable提交到TaskExecutor ,使用一个单独的线程进行处理。
3、DispatcherServlet和所有Filters退出Web容器线程,但response保持打开状态。
4、Callable返回结果,Spring MVC将请求发送回Servlet容器以完成处理。
5、根据callable返回的结果。SpringMVC 继续进行视图渲染等流程(从收到请求-视图渲染)
maven环境
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yu</groupId>
<artifactId>springMVC</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.11.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.8</source> <!-- Java版本号 -->
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
新建一个contourller类
package com.yu.Controller;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.DeferredResult;
@Controller
public class AsyncController {
@ResponseBody
@RequestMapping("/quo")
public DeferredResult<Object> quotes11() {
//登待3秒 如果还没有谁调用setResult();这个方法就返回一个eorr
DeferredResult<Object> deferredResult = new DeferredResult<Object>((long)3000,"eorr");
DeferredResultQueue.save(deferredResult);
return deferredResult;
}
@ResponseBody
@RequestMapping("/getss")
public String getss() {
String name = UUID.randomUUID().toString();
DeferredResult<Object> deferredResult = DeferredResultQueue.get();
deferredResult.setResult(name);
return "success====>"+name;
}
@ResponseBody
@RequestMapping("/ns")
public Callable<String> nsync01() {
System.out.println("主线程开始执行:"+Thread.currentThread().getName());
Callable<String> callable = new Callable<String>(){
@Override
public String call() throws Exception {
System.out.println("副线程开始执行:"+Thread.currentThread().getName());
TimeUnit.SECONDS.sleep(2L);
System.out.println("副线程开始执行:"+Thread.currentThread().getName());
return "nsync01......";
}
};
System.out.println("主线程执行结束:"+Thread.currentThread().getName());
return callable;
}
}
定义一个DeferredResultQueue用于保存信息的类
package com.yu.Controller;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import org.springframework.web.context.request.async.DeferredResult;
public class DeferredResultQueue {
private static Queue<DeferredResult<Object>> queue = new ConcurrentLinkedQueue<>();
public static void save(DeferredResult<Object> deferredResult){
queue.add(deferredResult);
}
public static DeferredResult<Object> get(){
return queue.poll();
}
}
测试的结果
http://127.0.0.1:8080/springMVC/quo
http://127.0.0.1:8080/springMVC/getss