Spring MVC 的http请求处理过程

Spring3.2请求处理大致过程

处理过程

  • 初始化:

    • DispatcherServlet.onRefresh()
    • DispatcherServlet.initStrategies()
    • DispatcherServlet.initHandlerMappings()
  • 处理请求:

    • DispatcherServlet.doDispatch()
    • RequestMappingHandlerAdapter.handle()
    • RequestMappingHandlerAdapter.handleInternal()
    • RequestMappingHandlerAdapter.invokeHandleMethod()
    • WebAsyncManager.setTaskExecutor()
    • WebAsyncManager.setAsyncWebRequest()
    • WebAsyncManager.registerCallableInterceptors()
    • WebAsyncManager.registerDeferredResultInterceptors()
    • ServletInvocableHandlerMethod.invokeAndHandle()
    • CallableMethodReturnValueHandler/DeferredResultMethodReturnValueHandler.handleReturnValue()
    • WebAsyncManager.startCallableProcessing()/WebAsyncManager.startDeferredResultProcessing()

代码详述

DispatcherServlet.java

在onRefresh时,初始化
       
 
 
[java] view plain copy
  1. /** 
  2.        * This implementation calls {@link #initStrategies}. 
  3.        */  
  4.       @Override  
  5.       protected void onRefresh(ApplicationContext context) {  
  6.           initStrategies(context);  
  7.       }  
  8.   
  9.       /** 
  10.        * Initialize the strategy objects that this servlet uses. 
  11.        * <p>May be overridden in subclasses in order to initialize further strategy objects. 
  12.        */  
  13.       protected void initStrategies(ApplicationContext context) {  
  14.           initMultipartResolver(context);  
  15.           initLocaleResolver(context);  
  16.           initThemeResolver(context);  
  17.           initHandlerMappings(context);//初始化Handler映射,例如@RequestMapping(value = "/something", method = RequestMethod.PUT)  
  18.           initHandlerAdapters(context);  
  19.           initHandlerExceptionResolvers(context);  
  20.           initRequestToViewNameTranslator(context);  
  21.           initViewResolvers(context);  
  22.           initFlashMapManager(context);  
  23.       }  
  24.   
  25.   
  26.   
  27.       /** 
  28.        * Initialize the HandlerMappings used by this class. 
  29.        * <p>If no HandlerMapping beans are defined in the BeanFactory for this namespace, 
  30.        * we default to BeanNameUrlHandlerMapping. 
  31.        */  
  32.       private void initHandlerMappings(ApplicationContext context) {  
  33.           this.handlerMappings = null;  
  34.   
  35.           if (this.detectAllHandlerMappings) {  
  36.               // Find all HandlerMappings in the ApplicationContext, including ancestor contexts.  
  37.               Map<String, HandlerMapping> matchingBeans =  
  38.                       BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.classtruefalse);//从Context中,找@RequestMapping,构建映射关系  
  39.               if (!matchingBeans.isEmpty()) {  
  40.                   this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values());  
  41.                   // We keep HandlerMappings in sorted order.  
  42.                   OrderComparator.sort(this.handlerMappings);  
  43.               }  
  44.           }  
  45.           else {  
  46.               try {  
  47.                   HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);//缺省  
  48.                   this.handlerMappings = Collections.singletonList(hm);  
  49.               }  
  50.               catch (NoSuchBeanDefinitionException ex) {  
  51.                   // Ignore, we'll add a default HandlerMapping later.  
  52.               }  
  53.           }  
  54.   
  55.           // Ensure we have at least one HandlerMapping, by registering  
  56.           // a default HandlerMapping if no other mappings are found.  
  57.           if (this.handlerMappings == null) {  
  58.               this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);  
  59.               if (logger.isDebugEnabled()) {  
  60.                   logger.debug("No HandlerMappings found in servlet '" + getServletName() + "': using default");  
  61.               }  
  62.           }  
  63.       }  
处理请求时,找handlerAdapter处理请求
       
 
 
[java] view plain copy
  1. /** 
  2.         * Process the actual dispatching to the handler. 
  3.         * <p>The handler will be obtained by applying the servlet's HandlerMappings in order. 
  4.         * The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters 
  5.         * to find the first that supports the handler class. 
  6.         * <p>All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers 
  7.         * themselves to decide which methods are acceptable. 
  8.         * @param request current HTTP request 
  9.         * @param response current HTTP response 
  10.         * @throws Exception in case of any kind of processing failure 
  11.         */  
  12.        protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {  
  13.            HttpServletRequest processedRequest = request;  
  14.            HandlerExecutionChain mappedHandler = null;  
  15.            boolean multipartRequestParsed = false;  
  16.   
  17.            WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);//获取WebAsyncManager  
  18.   
  19.            try {  
  20.                ModelAndView mv = null;  
  21.                Exception dispatchException = null;  
  22.   
  23.                try {  
  24.                    processedRequest = checkMultipart(request);  
  25.                    multipartRequestParsed = processedRequest != request;  
  26.   
  27.                    // Determine handler for the current request.  
  28.                    mappedHandler = getHandler(processedRequest, false);//获取HandlerExecutionChain  
  29.                    if (mappedHandler == null || mappedHandler.getHandler() == null) {  
  30.                        noHandlerFound(processedRequest, response);  
  31.                        return;  
  32.                    }  
  33.   
  34.                    // Determine handler adapter for the current request.  
  35.                    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());//获取映射处理封装类  
  36.   
  37.                    // Process last-modified header, if supported by the handler.  
  38.                    String method = request.getMethod();  
  39.                    boolean isGet = "GET".equals(method);  
  40.                    if (isGet || "HEAD".equals(method)) {  
  41.                        long lastModified = ha.getLastModified(request, mappedHandler.getHandler());  
  42.                        if (logger.isDebugEnabled()) {  
  43.                            String requestUri = urlPathHelper.getRequestUri(request);  
  44.                            logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);  
  45.                        }  
  46.                        if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {  
  47.                            return;  
  48.                        }  
  49.                    }  
  50.   
  51.                    if (!mappedHandler.applyPreHandle(processedRequest, response)) {  
  52.                        return;  
  53.                    }  
  54.   
  55.                    try {  
  56.                        // Actually invoke the handler.  
  57.                        mv = ha.handle(processedRequest, response, mappedHandler.getHandler());//调用handler处理  
  58.                    }  
  59.                    finally {  
  60.                        if (asyncManager.isConcurrentHandlingStarted()) {  
  61.                            return;  
  62.                        }  
  63.                    }  
  64.   
  65.                    applyDefaultViewName(request, mv);  
  66.                    mappedHandler.applyPostHandle(processedRequest, response, mv);  
  67.                }  
  68.                catch (Exception ex) {  
  69.                    dispatchException = ex;  
  70.                }  
  71.                processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);  
  72.            }  
  73.            catch (Exception ex) {  
  74.                triggerAfterCompletion(processedRequest, response, mappedHandler, ex);  
  75.            }  
  76.            catch (Error err) {  
  77.                triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);  
  78.            }  
  79.            finally {  
  80.                if (asyncManager.isConcurrentHandlingStarted()) {  
  81.                    // Instead of postHandle and afterCompletion  
  82.                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);  
  83.                    return;  
  84.                }  
  85.                // Clean up any resources used by a multipart request.  
  86.                if (multipartRequestParsed) {  
  87.                    cleanupMultipart(processedRequest);  
  88.                }  
  89.            }  
  90.        }  
  91.   
  92.   
  93.        /** 
  94.         * Return the HandlerExecutionChain for this request. 
  95.         * <p>Tries all handler mappings in order. 
  96.         * @param request current HTTP request 
  97.         * @return the HandlerExecutionChain, or <code>null</code> if no handler could be found 
  98.         */  
  99.        protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {  
  100.            for (HandlerMapping hm : this.handlerMappings) {  
  101.                if (logger.isTraceEnabled()) {  
  102.                    logger.trace(  
  103.                            "Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");  
  104.                }  
  105.                HandlerExecutionChain handler = hm.getHandler(request);  
  106.                if (handler != null) {  
  107.                    return handler;  
  108.                }  
  109.            }  
  110.            return null;  
  111.        }  

RequestMappingHandlerAdapter.java

调用handle方法处理,handle调用handleInternal方法
        
 
 
[java] view plain copy
  1. protected final ModelAndView handleInternal(HttpServletRequest request,  
  2.                 HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {  
  3.   
  4.             if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {  
  5.                 // Always prevent caching in case of session attribute management.  
  6.                 checkAndPrepare(request, response, this.cacheSecondsForSessionAttributeHandlers, true);  
  7.             }  
  8.             else {  
  9.                 // Uses configured default cacheSeconds setting.  
  10.                 checkAndPrepare(request, response, true);  
  11.             }  
  12.   
  13.             // Execute invokeHandlerMethod in synchronized block if required.  
  14.             if (this.synchronizeOnSession) {  
  15.                 HttpSession session = request.getSession(false);  
  16.                 if (session != null) {  
  17.                     Object mutex = WebUtils.getSessionMutex(session);  
  18.                     synchronized (mutex) {  
  19.                         return invokeHandleMethod(request, response, handlerMethod);  
  20.                     }  
  21.                 }  
  22.             }  
  23.   
  24.             return invokeHandleMethod(request, response, handlerMethod);  
  25.         }  
  26. 调用invokeHandleMethod  
  27.       /** 
  28.          * Invoke the {@link RequestMapping} handler method preparing a {@link ModelAndView} if view resolution is required. 
  29.          */  
  30.         private ModelAndView invokeHandleMethod(HttpServletRequest request,  
  31.                 HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {  
  32.   
  33.             ServletWebRequest webRequest = new ServletWebRequest(request, response);  
  34.   
  35.             WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);  
  36.             ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);  
  37.             ServletInvocableHandlerMethod requestMappingMethod = createRequestMappingMethod(handlerMethod, binderFactory);//创建请求映射方法,注意这里会设置  
  38.   
  39.             ModelAndViewContainer mavContainer = new ModelAndViewContainer();  
  40.             mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));  
  41.             modelFactory.initModel(webRequest, mavContainer, requestMappingMethod);  
  42.             mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);  
  43.   
  44.             //异步初始化  
  45.             AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);  
  46.             asyncWebRequest.setTimeout(this.asyncRequestTimeout);  
  47.   
  48.             final WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);  
  49.             asyncManager.setTaskExecutor(this.taskExecutor);//设置执行类AsyncManager会用到  
  50.             asyncManager.setAsyncWebRequest(asyncWebRequest);  
  51.             asyncManager.registerCallableInterceptors(this.callableInterceptors);  
  52.             asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);  
  53.   
  54.             if (asyncManager.hasConcurrentResult()) {  
  55.                 Object result = asyncManager.getConcurrentResult();  
  56.                 mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];  
  57.                 asyncManager.clearConcurrentResult();  
  58.   
  59.                 if (logger.isDebugEnabled()) {  
  60.                     logger.debug("Found concurrent result value [" + result + "]");  
  61.                 }  
  62.                 requestMappingMethod = requestMappingMethod.wrapConcurrentResult(result);  
  63.             }  
  64.   
  65.             requestMappingMethod.invokeAndHandle(webRequest, mavContainer);  
  66.   
  67.             if (asyncManager.isConcurrentHandlingStarted()) {  
  68.                 return null;  
  69.             }  
  70.   
  71.             return getModelAndView(mavContainer, modelFactory, webRequest);  
  72.         }  
  73.   
  74.   
  75.         private ServletInvocableHandlerMethod createRequestMappingMethod(  
  76.                 HandlerMethod handlerMethod, WebDataBinderFactory binderFactory) {  
  77.   
  78.             ServletInvocableHandlerMethod requestMethod;  
  79.             requestMethod = new ServletInvocableHandlerMethod(handlerMethod);  
  80.             requestMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);  
  81.             requestMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);//注入ReturnValueHandlers  
  82.             requestMethod.setDataBinderFactory(binderFactory);  
  83.             requestMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);  
  84.             return requestMethod;  
  85.         }  
  86.   
  87.   
  88.         /** 
  89.          * Configure the complete list of supported return value types thus 
  90.          * overriding handlers that would otherwise be configured by default. 
  91.          */  
  92.          //如果需要异步处理,需要注入例如DeferredResultMethodReturnValueHandler等  
  93.         public void setReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {  
  94.             if (returnValueHandlers == null) {  
  95.                 this.returnValueHandlers = null;  
  96.             }  
  97.             else {  
  98.                 this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite();  
  99.                 this.returnValueHandlers.addHandlers(returnValueHandlers);  
  100.             }  
  101.         }  
  102.   
  103.         /** 
  104.          * Default constructor. 
  105.          */  
  106.         public RequestMappingHandlerAdapter() {  
  107.   
  108.             StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();  
  109.             stringHttpMessageConverter.setWriteAcceptCharset(false); // See SPR-7316  
  110.   
  111.             this.messageConverters = new ArrayList<HttpMessageConverter<?>>();//converter均集成HttpMessageConverter来拦截http请求  
  112.             this.messageConverters.add(new ByteArrayHttpMessageConverter());  
  113.             this.messageConverters.add(stringHttpMessageConverter);  
  114.             this.messageConverters.add(new SourceHttpMessageConverter<Source>());  
  115.             this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());  
  116.         }  
  117.   
  118.       /** 
  119.          * Provide the converters to use in argument resolvers and return value 
  120.          * handlers that support reading and/or writing to the body of the 
  121.          * request and response. 
  122.          */  
  123.         public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters) {  
  124.             this.messageConverters = messageConverters;  
  125.         }  
  126.   
  127.   
  128.         /** 
  129.          * Set the default {@link AsyncTaskExecutor} to use when a controller method 
  130.          * return a {@link Callable}. Controller methods can override this default on 
  131.          * a per-request basis by returning an {@link WebAsyncTask}. 
  132.          * <p>By default a {@link SimpleAsyncTaskExecutor} instance is used. 
  133.          * It's recommended to change that default in production as the simple executor 
  134.          * does not re-use threads. 
  135.          */  
  136.          //设置异步执行类,给AsyncManager调用  
  137.         public void setTaskExecutor(AsyncTaskExecutor taskExecutor) {  
  138.             this.taskExecutor = taskExecutor;  
  139.         }  

ServletInvocableHandlerMethod.java

调用invokeAndHandle
       
 
 
[java] view plain copy
  1. /** 
  2.         * Invokes the method and handles the return value through a registered 
  3.         * {@link HandlerMethodReturnValueHandler}. 
  4.         * 
  5.         * @param webRequest the current request 
  6.         * @param mavContainer the ModelAndViewContainer for this request 
  7.         * @param providedArgs "given" arguments matched by type, not resolved 
  8.         */  
  9.        public final void invokeAndHandle(ServletWebRequest webRequest,  
  10.                ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {  
  11.   
  12.            Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);  
  13.   
  14.            setResponseStatus(webRequest);  
  15.   
  16.            if (returnValue == null) {  
  17.                if (isRequestNotModified(webRequest) || hasResponseStatus() || mavContainer.isRequestHandled()) {  
  18.                    mavContainer.setRequestHandled(true);  
  19.                    return;  
  20.                }  
  21.            }  
  22.            else if (StringUtils.hasText(this.responseReason)) {  
  23.                mavContainer.setRequestHandled(true);  
  24.                return;  
  25.            }  
  26.   
  27.            mavContainer.setRequestHandled(false);//异步处理,表示没有处理完毕  
  28.   
  29.            try {//调用HandlerMethodReturnValueHandler做异步处理,returnValue为DeferredResult or Callable or  
  30.                this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);  
  31.            }  
  32.            catch (Exception ex) {  
  33.                if (logger.isTraceEnabled()) {  
  34.                    logger.trace(getReturnValueHandlingErrorMessage("Error handling return value", returnValue), ex);  
  35.                }  
  36.                throw ex;  
  37.            }  
  38.        }  

CallableMethodReturnValueHandler.java

调用handleReturnValue方法
       
 
 
[java] view plain copy
  1. public void handleReturnValue(Object returnValue,  
  2.                MethodParameter returnType, ModelAndViewContainer mavContainer,  
  3.                NativeWebRequest webRequest) throws Exception {  
  4.   
  5.            if (returnValue == null) {  
  6.                mavContainer.setRequestHandled(true);  
  7.                return;  
  8.            }  
  9.   
  10.            Callable<?> callable = (Callable<?>) returnValue;  
  11.            WebAsyncUtils.getAsyncManager(webRequest).startCallableProcessing(callable, mavContainer);  
  12.        }     

DeferredResultMethodReturnValueHandler.java

调用handleReturnValue方法
        
 
 
[java] view plain copy
  1. public void handleReturnValue(Object returnValue,  
  2.             MethodParameter returnType, ModelAndViewContainer mavContainer,  
  3.             NativeWebRequest webRequest) throws Exception {  
  4.   
  5.         if (returnValue == null) {  
  6.             mavContainer.setRequestHandled(true);  
  7.             return;  
  8.         }  
  9.   
  10.         DeferredResult<?> deferredResult = (DeferredResult<?>) returnValue;  
  11.         WebAsyncUtils.getAsyncManager(webRequest).startDeferredResultProcessing(deferredResult, mavContainer);  
  12.      }    

WebAsyncManager.java 参考Spring Servlet3 扩展模块笔记

调用startCallableProcessing方法
       
 
 
[java] view plain copy
  1. /** 
  2.         * Start concurrent request processing and execute the given task with an 
  3.         * {@link #setTaskExecutor(AsyncTaskExecutor) AsyncTaskExecutor}. The result 
  4.         * from the task execution is saved and the request dispatched in order to 
  5.         * resume processing of that result. If the task raises an Exception then 
  6.         * the saved result will be the raised Exception. 
  7.         * 
  8.         * @param callable a unit of work to be executed asynchronously 
  9.         * @param processingContext additional context to save that can be accessed 
  10.         * via {@link #getConcurrentResultContext()} 
  11.         * @throws Exception If concurrent processing failed to start 
  12.         * 
  13.         * @see #getConcurrentResult() 
  14.         * @see #getConcurrentResultContext() 
  15.         */  
  16.        @SuppressWarnings({ "rawtypes""unchecked" })  
  17.        public void startCallableProcessing(final Callable<?> callable, Object... processingContext) throws Exception {  
  18.            Assert.notNull(callable, "Callable must not be null");  
  19.            startCallableProcessing(new WebAsyncTask(callable), processingContext);  
  20.        }  
  21.   
  22.        /** 
  23.         * Use the given {@link WebAsyncTask} to configure the task executor as well as 
  24.         * the timeout value of the {@code AsyncWebRequest} before delegating to 
  25.         * {@link #startCallableProcessing(Callable, Object...)}. 
  26.         * 
  27.         * @param webAsyncTask an WebAsyncTask containing the target {@code Callable} 
  28.         * @param processingContext additional context to save that can be accessed 
  29.         * via {@link #getConcurrentResultContext()} 
  30.         * @throws Exception If concurrent processing failed to start 
  31.         */  
  32.        public void startCallableProcessing(final WebAsyncTask<?> webAsyncTask, Object... processingContext) throws Exception {  
  33.            Assert.notNull(webAsyncTask, "WebAsyncTask must not be null");  
  34.            Assert.state(this.asyncWebRequest != null"AsyncWebRequest must not be null");  
  35.   
  36.            Long timeout = webAsyncTask.getTimeout();  
  37.            if (timeout != null) {  
  38.                this.asyncWebRequest.setTimeout(timeout);  
  39.            }  
  40.   
  41.            AsyncTaskExecutor executor = webAsyncTask.getExecutor();  
  42.            if (executor != null) {  
  43.                this.taskExecutor = executor;  
  44.            }  
  45.   
  46.            List<CallableProcessingInterceptor> interceptors = new ArrayList<CallableProcessingInterceptor>();  
  47.            interceptors.add(webAsyncTask.getInterceptor());  
  48.            interceptors.addAll(this.callableInterceptors.values());  
  49.            interceptors.add(timeoutCallableInterceptor);  
  50.   
  51.            final Callable<?> callable = webAsyncTask.getCallable();  
  52.            final CallableInterceptorChain interceptorChain = new CallableInterceptorChain(interceptors);  
  53.   
  54.            this.asyncWebRequest.addTimeoutHandler(new Runnable() {  
  55.                public void run() {  
  56.                    logger.debug("Processing timeout");  
  57.                    Object result = interceptorChain.triggerAfterTimeout(asyncWebRequest, callable);  
  58.                    if (result != CallableProcessingInterceptor.RESULT_NONE) {  
  59.                        setConcurrentResultAndDispatch(result);  
  60.                    }  
  61.                }  
  62.            });  
  63.   
  64.            this.asyncWebRequest.addCompletionHandler(new Runnable() {  
  65.                public void run() {  
  66.                    interceptorChain.triggerAfterCompletion(asyncWebRequest, callable);  
  67.                }  
  68.            });  
  69.   
  70.            interceptorChain.applyBeforeConcurrentHandling(asyncWebRequest, callable);  
  71.   
  72.            startAsyncProcessing(processingContext);  
  73.   
  74.            this.taskExecutor.submit(new Runnable() {  
  75.                public void run() {  
  76.                    Object result = null;  
  77.                    try {  
  78.                        interceptorChain.applyPreProcess(asyncWebRequest, callable);  
  79.                        result = callable.call();  
  80.                    }  
  81.                    catch (Throwable t) {  
  82.                        result = t;  
  83.                    }  
  84.                    finally {  
  85.                        result = interceptorChain.applyPostProcess(asyncWebRequest, callable, result);  
  86.                    }  
  87.                    setConcurrentResultAndDispatch(result);  
  88.                }  
  89.            });  
  90.        }  
调用startDeferredResultProcessing方法
        
 
 
[java] view plain copy
  1. /** 
  2.          * Start concurrent request processing and initialize the given 
  3.          * {@link DeferredResult} with a {@link DeferredResultHandler} that saves 
  4.          * the result and dispatches the request to resume processing of that 
  5.          * result. The {@code AsyncWebRequest} is also updated with a completion 
  6.          * handler that expires the {@code DeferredResult} and a timeout handler 
  7.          * assuming the {@code DeferredResult} has a default timeout result. 
  8.          * 
  9.          * @param deferredResult the DeferredResult instance to initialize 
  10.          * @param processingContext additional context to save that can be accessed 
  11.          * via {@link #getConcurrentResultContext()} 
  12.          * @throws Exception If concurrent processing failed to start 
  13.          * 
  14.          * @see #getConcurrentResult() 
  15.          * @see #getConcurrentResultContext() 
  16.          */  
  17.         public void startDeferredResultProcessing(  
  18.                 final DeferredResult<?> deferredResult, Object... processingContext) throws Exception {  
  19.   
  20.             Assert.notNull(deferredResult, "DeferredResult must not be null");  
  21.             Assert.state(this.asyncWebRequest != null"AsyncWebRequest must not be null");  
  22.   
  23.             Long timeout = deferredResult.getTimeoutValue();  
  24.             if (timeout != null) {  
  25.                 this.asyncWebRequest.setTimeout(timeout);  
  26.             }  
  27.   
  28.             List<DeferredResultProcessingInterceptor> interceptors = new ArrayList<DeferredResultProcessingInterceptor>();  
  29.             interceptors.add(deferredResult.getInterceptor());  
  30.             interceptors.addAll(this.deferredResultInterceptors.values());  
  31.             interceptors.add(timeoutDeferredResultInterceptor);  
  32.   
  33.             final DeferredResultInterceptorChain interceptorChain = new DeferredResultInterceptorChain(interceptors);  
  34.   
  35.             this.asyncWebRequest.addTimeoutHandler(new Runnable() {  
  36.                 public void run() {  
  37.                     try {  
  38.                         interceptorChain.triggerAfterTimeout(asyncWebRequest, deferredResult);  
  39.                     }  
  40.                     catch (Throwable t) {  
  41.                         setConcurrentResultAndDispatch(t);  
  42.                     }  
  43.                 }  
  44.             });  
  45.   
  46.             this.asyncWebRequest.addCompletionHandler(new Runnable() {  
  47.                 public void run() {  
  48.                     interceptorChain.triggerAfterCompletion(asyncWebRequest, deferredResult);  
  49.                 }  
  50.             });  
  51.   
  52.             interceptorChain.applyBeforeConcurrentHandling(asyncWebRequest, deferredResult);  
  53.   
  54.             startAsyncProcessing(processingContext);  
  55.   
  56.             try {  
  57.                 interceptorChain.applyPreProcess(this.asyncWebRequest, deferredResult);  
  58.                 deferredResult.setResultHandler(new DeferredResultHandler() {  
  59.                     public void handleResult(Object result) {  
  60.                         result = interceptorChain.applyPostProcess(asyncWebRequest, deferredResult, result);  
  61.                         setConcurrentResultAndDispatch(result);  
  62.                     }  
  63.                 });  
  64.             }  
  65.             catch (Throwable t) {  
  66.                 setConcurrentResultAndDispatch(t);  
  67.             }  
  68.         }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值