SpringMVC的运行流程

 

1. 用户向服务器发送请求,请求被Spring 前端控制Servelt DispatcherServlet捕获;
2. DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI)。然后根据该URI,调用HandlerMapping获得该Handler配置的所有相关的对象,以
    HandlerExecutionChain对象的形式返回。
3. DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(...)方法)
4. 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。
  在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作:
  1)HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
  2)数据转换:对请求消息进行数据转换。如String转换成Integer、Double等
  3)数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期等
  4)数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
5. Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
6. 根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;
7. ViewResolver 结合Model和View,来渲染视图
8. 将渲染结果返回给客户端。

核心源码

@Override
    protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
         if (logger.isDebugEnabled()) {
             String requestUri = urlPathHelper.getRequestUri(request);
             String resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult() ? " resumed" : "";
             logger.debug("DispatcherServlet with name '" + getServletName() + "'" + resumed +
                     " processing " + request.getMethod() + " request for [" + requestUri + "]");
         }

         Map<String, Object> attributesSnapshot = null;
         if (WebUtils.isIncludeRequest(request)) {
             logger.debug("Taking snapshot of request attributes before include");
             attributesSnapshot = new HashMap<String, Object>();
             Enumeration<?> attrNames = request.getAttributeNames();
             while (attrNames.hasMoreElements()) {
                 String attrName = (String) attrNames.nextElement();
                 if (this.cleanupAfterInclude || attrName.startsWith("org.springframework.web.servlet")) {
                     attributesSnapshot.put(attrName, request.getAttribute(attrName));
                 }
             }
         }

        request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
        request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
        request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
        request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());

         FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
         if (inputFlashMap != null) {
             request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
         }
        request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
        request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);

         try {
             doDispatch(request, response);
         }
         finally {
             if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
                 return;
             }
             if (attributesSnapshot != null) {
                 restoreAttributesAfterInclude(request, attributesSnapshot);
             }
         }
    }

    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
         HttpServletRequest processedRequest = request;
         HandlerExecutionChain mappedHandler = null;
         boolean multipartRequestParsed = false;

         WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

         try {
             ModelAndView mv = null;
             Exception dispatchException = null;

             try {
                 processedRequest = checkMultipart(request);
                 multipartRequestParsed = processedRequest != request;

                 mappedHandler = getHandler(processedRequest);
                 if (mappedHandler == null || mappedHandler.getHandler() == null) {
                     noHandlerFound(processedRequest, response);
                     return;
                 }

                 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

                 String method = request.getMethod();
                 boolean isGet = "GET".equals(method);
                 if (isGet || "HEAD".equals(method)) {
                     long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                     if (logger.isDebugEnabled()) {
                          String requestUri = urlPathHelper.getRequestUri(request);
                         logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);
                     }
                     if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
                          return;
                     }
                 }
                 if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                     return;
                 }
                 try {
                     mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                 }
                 finally {
                     if (asyncManager.isConcurrentHandlingStarted()) {
                          return;
                     }
                 }
                 applyDefaultViewName(request, mv);
                 mappedHandler.applyPostHandle(processedRequest, response, mv);
             }
             catch (Exception ex) {
                 dispatchException = ex;
             }
             processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
         }
         catch (Exception ex) {
             triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
         }
         catch (Error err) {
             triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
         }
         finally {
             if (asyncManager.isConcurrentHandlingStarted()) {
                 mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                 return;
             }
             if (multipartRequestParsed) {
                 cleanupMultipart(processedRequest);
             }
         }
    }

 

posted @ 2019-05-17 14:47  我的博客我的人生  阅读(250)  评论(0编辑  收藏  举报