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);
    }
}
02-10 14:38