异步处理REST服务
Spring mvc 中支持两种异步执行方法的方式,第一种:使用Callable<>接口, 第二种使用: DeferredResult类
注意:如果你需要拦截异步的方法,在拦截器中实现Spring提供的相应方法即可,不然拦截不到
1、使用Callable接口实现
我们在Controller方法中使用Callable接口创建一个子线程用来处理我们的业务,然后直接返回Callable<?>,这样主方法很快就运行完成,而请求响应需要等子线程运行完成,代码如:
/**
* 使用Callable接口
*
* @return
*/
@GetMapping("/call")
public Callable<String> asyncCallableMethod() {
System.out.println("main exec");
Callable<String> result = new Callable<String>() {
@Override
public String call() throws InterruptedException {
System.out.println("son exec");
Thread.sleep(1000);
System.out.println("son end");
return "result";
}
};
System.out.println("main end");
return result;
}
2、使用DeferredResult类
和Callable接口一样,我们在Controller 中返回DeferredResult即可。和Runnable方式不同,在代码中我们看不到子线程的创建,我们只需要创建除DeferredResult对象,使用setResult()赋值即可,如果没有使用setResult赋值,请求端会得不到响应。代码如下:
/**
* 使用DeferredResult
*
* @return
* @throws InterruptedException
*/
@GetMapping("/deferred")
public DeferredResult<String> asyncDeferredResultMethod() throws InterruptedException {
System.out.println("main method exec");
// 创建对象
// DeferredResult 的result空时 前台收不到响应,直到有值 响应到前端
DeferredResult<String> deferredResult = new DeferredResult<>();
deferredResultMap.put("task", deferredResult);
System.out.println("main method end");
return deferredResult;
}
/**
* deferredResult 赋值
* 此方法不执行,访问 asyncDeferredResultMethod() 的请求都收不到响应
* @param result
* @return
*/
@GetMapping("/setVal")
public String deferredResultHandle(String result) {
// asyncDeferredResultMethod()返回值就是这里赋的值。
deferredResultMap.get("task").setResult(result);
return "set value success !";
}
异步请求这两个我用到的很少,所以记下来以备及时之需。