15.SpringMVC之异步请求
SpringMVC中异步请求相关组件1765243235
SpringMVC在此基础上对异步请求进行了封装。提供了AsyncWebRequest
类型的request,并提供了处理异步请求的管理器WebAsyncManager
和工具WebAsyncUtils
.
SpringMVC将异步请求返回值细分为了:Callable,WebAsyncTask,,DeferredResult 和 ListenableFuture
. 后续会针对这四种不同的类型一一分析。
AsyncWebRequest
AsyncWebRequest
,它是专门处理异步请求的request,定义如下:
//org.springframework.web.context.request.async.AsyncWebRequest
public interface AsyncWebRequest extends NativeWebRequest {
void setTimeout(Long timeout);
//相当于在AsyncListener中的`onTimeout和onComplete`
void addTimeoutHandler(Runnable runnable);
void addCompletionHandler(Runnable runnable);
void startAsync();
//判断异步请求是否开启和结束
boolean isAsyncStarted();
boolean isAsyncComplete();
void dispatch();
}
知识兔AsyncWebRequest
有两个实现类,
NoSupportAsyncWebRequest
: 不支持异步请求StandardServletAsyncWebRequest
: 支持异步请求。
StandardServletAsyncWebRequest
除了实现了AsyncWebRequest
接口外,还实现了AsyncListener
,另外它还继承了ServletWebRequest
.
public class StandardServletAsyncWebRequest extends ServletWebRequest implements AsyncWebRequest, AsyncListener {
private Long timeout;
//封装 AsyncContext 属性
private AsyncContext asyncContext;
private AtomicBoolean asyncCompleted = new AtomicBoolean(false);
//AsyncListener onTimeout,onCompletion方法 调用如下handlers..
private final List<Runnable> timeoutHandlers = new ArrayList<Runnable>();
private final List<Runnable> completionHandlers = new ArrayList<Runnable>();
@Override
public boolean isAsyncStarted() {
return ((this.asyncContext != null) && getRequest().isAsyncStarted());
}
@Override
public void startAsync() {
if (isAsyncStarted()) {
return;
}
this.asyncContext = getRequest().startAsync(getRequest(), getResponse());
this.asyncContext.addListener(this);
if (this.timeout != null) {
this.asyncContext.setTimeout(this.timeout);
}
}
// --- 实现 AsyncListener 方法----
@Override
public void onTimeout(AsyncEvent event) throws IOException {
for (Runnable handler : this.timeoutHandlers) {
handler.run();
}
}
知识兔@Override public void onComplete(AsyncEvent event) throws IOException { for (Runnable handler : this.completionHandlers) { handler.run(); } //执行完完成时,清空asyncContext this.asyncContext = null; this.asyncCompleted.set(true); }}