/根据当前请求与响应创建异步请求
AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
//设置异步请求的超时时间为当前组件中配置的超时时间
asyncWebRequest.setTimeout(this.asyncRequestTimeout);
//获取异步管理器
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
//设置异步管理器的任务执行器为当前组件中配置的任务执行器
asyncManager.setTaskExecutor(this.taskExecutor);
//设置异步管理器管理的异步请求实例
asyncManager.setAsyncWebRequest(asyncWebRequest);
//向异步管理器中注册Callable拦截器,Callable拦截器来自于当前组件的配置
asyncManager.registerCallableInterceptors(this.callableInterceptors);
//向异步管理器中注册DeferredResult拦截器,DeferredResult拦截器来自于当前组件的配置
asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);
//如果异步管理器中管理的异步请求已经有了结果
if (asyncManager.hasConcurrentResult()) {
//则获取异步执行结果
Object result = asyncManager.getConcurrentResult();
//获取异步系欸过上下文中维护的ModelAndView容器
mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
//清理异步管理器的结果,减少内存占用
asyncManager.clearConcurrentResult();
LogFormatUtils.traceDebug(logger, traceOn -> {
String formatted = LogFormatUtils.formatValue(result, !traceOn);
return "Resume with async result [" + formatted + "]";
});
//把invocableMethod包装为返回result的方法
invocableMethod = invocableMethod.wrapConcurrentResult(result);
}
//调用处理器方法并处理返回值
invocableMethod.invokeAndHandle(webRequest, mavContainer);
//如果处理完成后,开启了异步请求并在处理中,说明返回值为一个异步结果,直接返回null,等待异步结果返回,再执行上面的获取异步结果逻辑
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}
异步请求会请求dodispatch主流程方法两次:
第一次是正常的流程,asyncManager.hasConcurrentResult()为false,然后走到invocableMethod.invokeAndHandle(webRequest, mavContainer)来;
第二次,asyncManager.hasConcurrentResult()为true,然后带着result进入到invocableMethod.invokeAndHandle(webRequest, mavContainer)方法来;
public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
setResponseStatus(webRequest);
if (returnValue == null) {
if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
disableContentCachingIfNecessary(webRequest);
mavContainer.setRequestHandled(true);
return;
}
}
else if (StringUtils.hasText(getResponseStatusReason())) {
mavContainer.setRequestHandled(true);
return;
}
mavContainer.setRequestHandled(false);
Assert.state(this.returnValueHandlers != null, "No return value handlers");
try {
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
}
catch (Exception ex) {
if (logger.isTraceEnabled()) {
logger.trace(formatErrorForReturnValue(returnValue), ex);
}
throw ex;
}
}
这个方法包括了参数解析和返回值解析这两个最为核心的部分,我们后边讲;
@GetMapping(value = {"/get2"})
@ResponseBody
public DeferredResult<String> say(){
DeferredResult<String> result = new DeferredResult<>();
new Timer().schedule(new TimerTask() {
public void run() {
result.setResult("2222");
}
}, 3000);
System.out.println("1111");
return result;
}
上面这个是一个关于异步管理的一个get请求
第一行的Object returnValue,执行了上面的get请求,可以看到是不为null的。就会走到下面
this.returnValueHandlers.handleReturnValue(
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);
if (handler == null) {
throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());
}
handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
}
HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);就是通过返回值的类型来选择返回值参数解析的;
可以看到第三个,就是我们get请求对应的返回值解析处理方法了;
然后我们来到handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);就是说利用刚才得到的返回值解析器处理返回值的时候到了;
来到DeferredResultMethodReturnValueHandler的handleReturnValue方法:
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
if (returnValue == null) {
mavContainer.setRequestHandled(true);
return;
}
DeferredResult<?> result;
if (returnValue instanceof DeferredResult) {
result = (DeferredResult<?>) returnValue;
}
else if (returnValue instanceof ListenableFuture) {
result = adaptListenableFuture((ListenableFuture<?>) returnValue);
}
else if (returnValue instanceof CompletionStage) {
result = adaptCompletionStage((CompletionStage<?>) returnValue);
}
else {
// Should not happen...
throw new IllegalStateException("Unexpected return value type: " + returnValue);
}
WebAsyncUtils.getAsyncManager(webRequest).startDeferredResultProcessing(result, mavContainer);
}
最主要是最底下的 WebAsyncUtils.getAsyncManager(webRequest).startDeferredResultProcessing(result, mavContainer);
这里边就是执行第二次dodispatch的关键所在:
拉到最底下找到setConcurrentResultAndDispatch(result);
private void setConcurrentResultAndDispatch(Object result) {
synchronized (WebAsyncManager.this) {
if (this.concurrentResult != RESULT_NONE) {
return;
}
this.concurrentResult = result;
this.errorHandlingInProgress = (result instanceof Throwable);
}
if (this.asyncWebRequest.isAsyncComplete()) {
if (logger.isDebugEnabled()) {
logger.debug("Async result set but request already complete: " + formatRequestUri());\
}
return;
}
if (logger.isDebugEnabled()) {
boolean isError = result instanceof Throwable;
logger.debug("Async " + (isError ? "error" : "result set") + ", dispatch to " + formatRequestUri());
}
this.asyncWebRequest.dispatch();
}
可以看到这里这个this.asyncWebRequest.dispatch();
我们再追下去,这个类其实已经是到tomcat的jar包下的文件了,我还没研究过tomcat,所以就走个过场,知道调用的流程就好了
点击最底下的action,
case ASYNC_DISPATCH: {
if (asyncStateMachine.asyncDispatch()) {
processSocketEvent(SocketEvent.OPEN_READ, true);
}
break;
}
会来到这个ASYNC_DISPATCH这里来,