SpringMVC运行流程及技术原理版权声明

原创
小哥 3年前 (2022-10-28) 阅读数 51 #大杂烩

图解SpringMVC执行流程:

SpringMVC执行流程

SpringMVC执行流程:
1.用户向前端控制器发送请求。DispatcherServlet
2.DispatcherServlet收到的请求调用处理器映射器HandlerMapping。
3.根据请求提供处理器映射器url找到特定的处理器并生成处理器执行链。HandlerExecutionChain(包括处理器对象和处理器拦截器。)一起归来DispatcherServlet。
4.DispatcherServlet根据处理器Handler获取处理器适配器HandlerAdapter执行HandlerAdapter处理参数封装、数据格式转换、数据验证等一系列操作。
5.执行处理器Handler(Controller,也称为页面控制器)。
6.Handler执行完成返回ModelAndView
7.HandlerAdapter将Handler执行结果ModelAndView返回到DispatcherServlet
8.DispatcherServlet将ModelAndView传给ViewReslover视图解析器
9.ViewReslover分析后返回特定View
10.DispatcherServlet对View来呈现视图(即模型数据)。model填充到视图中)。
11.DispatcherServlet对用户的响应。

当然,有以下几个表达式,但它们都与第一个相同。.

执行流程

我们分析了第一张图表。

组件说明:

1.DispatcherServlet:前端控制器。用户请求到达前端控制器,这是等价的。mvc模式中的c,dispatcherServlet是整个流程控制的中心,它调用其他组件来处理用户请求,dispatcherServlet组件的存在减少了组件之间的耦合。,提高了系统可伸缩性。由框架实施
2.HandlerMapping:处理器映射器。HandlerMapping负责用户的请求。url找到Handler就是处理器,springmvc提供不同的映射器来实现不同的映射方法,按照一定的规则查找。,例如:xml框架实现的配置模式、实现接口模式、注释模式等
3.Handler:处理器。Handler 是继DispatcherServlet前端控制器的后端控制器,在。DispatcherServlet的控制下Handler处理特定的用户请求。到期Handler它涉及到特定的用户业务请求,因此一般情况下需要程序员根据业务需求进行开发。Handler。
4.HandlAdapter:处理器适配器。通过HandlerAdapter处理器被执行,这是适配器模式的应用,并且可以通过扩展适配器执行更多类型的处理器。由框架实现。
5.ModelAndView是springmvc的封装对象的model和view封装在一起。
6.ViewResolver:查看解析器。ViewResolver负责生成处理结果View视图,ViewResolver首先,根据逻辑视图名称解析为物理视图名称,即具体的页面地址,然后生成。View查看对象,最后打开View执行呈现将通过页面向用户呈现过程的结果。
7View:是springmvc封装对象是一个接口。, springmvc框架提供了很多View视图类型,包括:jspview,pdfview,jstlView、freemarkerView、pdfView等。一般来说,模型数据需要通过页面通过页面标签或页面模板技术展示给用户,程序员需要根据业务需求开发特定的页面。

与执行进程对应的代码
1.请求到达前端控制器的第一站,并首先进行一些准备。

/**
 * Exposes the DispatcherServlet-specific request attributes and delegates to {@link #doDispatch}
 * for the actual dispatching.
 */
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
   if (logger.isDebugEnabled()) {
      String requestUri = urlPathHelper.getRequestUri(request);
      logger.debug("DispatcherServlet with name " + getServletName() + " processing " + request.getMethod() +
            " request for [" + requestUri + "]");
   }

    //保护现场
   // Keep a snapshot of the request attributes in case of an include,
   // to be able to restore the original attributes after the include.
   Map attributesSnapshot = null;
   if (WebUtils.isIncludeRequest(request)) {
      logger.debug("Taking snapshot of request attributes before include");
      attributesSnapshot = new HashMap();
      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,方便后端处理器和查看
   // Make framework objects available to handlers and view objects.
   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 {
      // Restore the original attribute snapshot, in case of an include.
      if (attributesSnapshot != null) {
         restoreAttributesAfterInclude(request, attributesSnapshot);
      }
   }
}

2.开始处理请求
//通过url查找HandlerMap最相似的key(url),然后由key获取HandlerMapping对象
//通过处理器映射器获取处理器;
//通过查询处理器适配器获得

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
   HttpServletRequest processedRequest = request;
   HandlerExecutionChain mappedHandler = null;
   int interceptorIndex = -1;

   try {
      ModelAndView mv;
      boolean errorView = false;

      try {
         processedRequest = checkMultipart(request);

         // Determine handler for the current request
        //步骤3.1~3.4用于获取包含的处理器。Handler和拦截器AdapterIntercepters处理器执行该链。HandlerExecutionChain
         mappedHandler = getHandler(processedRequest, false);
         if (mappedHandler == null || mappedHandler.getHandler() == null) {
            noHandlerFound(processedRequest, response);
            return;
         }

         // Determine handler adapter for the current request.
        //步骤4.1~4.2,根据HandlerExecutionChain处理器输入Handler获取处理器适配器
         HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

               // Process last-modified header, if supported by the handler.
         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;
            }
         }

         // Apply preHandle methods of registered interceptors.
         HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();
         if (interceptors != null) {
            for (int i = 0; i < interceptors.length; i++) {
               HandlerInterceptor interceptor = interceptors[i];
               if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {
                  triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
                  return;
               }
               interceptorIndex = i;
            }
         }

         // Actually invoke the handler.
        //5.1~5.3通过处理器适配器HandlerApapter调用处理器以完成请求的处理。
         mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

         // Do we need view name translation?
         if (mv != null && !mv.hasView()) {
            mv.setViewName(getDefaultViewName(request));
         }

         // Apply postHandle methods of registered interceptors.
         if (interceptors != null) {
            for (int i = interceptors.length - 1; i >= 0; i--) {
               HandlerInterceptor interceptor = interceptors[i];
               interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);
            }
         }
      }
      catch (ModelAndViewDefiningException ex) {
         logger.debug("ModelAndViewDefiningException encountered", ex);
         mv = ex.getModelAndView();
      }
      catch (Exception ex) {
         Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
         mv = processHandlerException(processedRequest, response, handler, ex);
         errorView = (mv != null);
      }

      // Did the handler return a view to render?
      if (mv != null && !mv.wasCleared()) {
         render(mv, processedRequest, response);
         if (errorView) {
            WebUtils.clearErrorRequestAttributes(request);
         }
      }
      else {
         if (logger.isDebugEnabled()) {
            logger.debug("Null ModelAndView returned to DispatcherServlet with name " + getServletName() +
                  ": assuming HandlerAdapter completed request handling");
         }
      }

      // Trigger after-completion for successful outcome.
      triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
   }

   catch (Exception ex) {
      // Trigger after-completion for thrown exception.
      triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
      throw ex;
   }
   catch (Error err) {
      ServletException ex = new NestedServletException("Handler processing failed", err);
      // Trigger after-completion for thrown exception.
      triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
      throw ex;
   }

   finally {
      // Clean up any resources used by a multipart request.
      if (processedRequest != request) {
         cleanupMultipart(processedRequest);
      }
   }
}

3.1 getHandler(HttpServletRequest request),经由HandlerMapping对象获取HandlerExecutionChain(处理器和拦截器)

/**
 * Return the HandlerExecutionChain for this request.
 * 

Tries all handler mappings in order. * @param request current HTTP request * @return the HandlerExecutionChain, or null if no handler could be found */ protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { for (HandlerMapping hm : this.handlerMappings) { if (logger.isTraceEnabled()) { logger.trace( "Testing handler map [" + hm + "] in DispatcherServlet with name " + getServletName() + ""); } HandlerExecutionChain handler = hm.getHandler(request); if (handler != null) { return handler; } } return null; }

3.2.1 getHandler(HttpServletRequest request),经由request把处理器拿来,把处理器拿来。Handler之后,获取拦截器并最终组成拦截器。HandlerExecutionChain

/**
 * Look up a handler for the given request, falling back to the default
 * handler if no specific one is found.
 * @param request current HTTP request
 * @return the corresponding handler instance, or the default handler
 * @see #getHandlerInternal
 */
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
   Object handler = getHandlerInternal(request);
   if (handler == null) {
      handler = getDefaultHandler();
   }
   if (handler == null) {
      return null;
   }
   // Bean name or resolved handler?
   if (handler instanceof String) {
      String handlerName = (String) handler;
      handler = getApplicationContext().getBean(handlerName);
   }
   return getHandlerExecutionChain(handler, request);
}

3.2.2 根据找到的处理器Handler和request获取包含Handler和AdaptedInterceptors的HandlerExecutionChain

protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
   HandlerExecutionChain chain = 
      (handler instanceof HandlerExecutionChain) ?
         (HandlerExecutionChain) handler : new HandlerExecutionChain(handler);

   chain.addInterceptors(getAdaptedInterceptors());

   String lookupPath = urlPathHelper.getLookupPathForRequest(request);
   for (MappedInterceptor mappedInterceptor : mappedInterceptors) {
      if (mappedInterceptor.matches(lookupPath, pathMatcher)) {
         chain.addInterceptor(mappedInterceptor.getInterceptor());
      }
   }

   return chain;
}
/**
 * Return the adapted interceptors as HandlerInterceptor array.
 * @return the array of HandlerInterceptors, or null if none
 */
protected final HandlerInterceptor[] getAdaptedInterceptors() {
   int count = adaptedInterceptors.size();
   return (count > 0) ? adaptedInterceptors.toArray(new HandlerInterceptor[count]) : null;
}

3.3.getHandlerInternal(HttpServletRequest request)获取Handler

/**
 * Look up a handler for the URL path of the given request.
 * @param request current HTTP request
 * @return the handler instance, or null if none found
 */
@Override
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
   String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
   Object handler = lookupHandler(lookupPath, request);
   if (handler == null) {
      // We need to care for the default handler directly, since we need to
      // expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well.
      Object rawHandler = null;
      if ("/".equals(lookupPath)) {
         rawHandler = getRootHandler();
      }
      if (rawHandler == null) {
         rawHandler = getDefaultHandler();
      }
      if (rawHandler != null) {
         // Bean name or resolved handler?
         if (rawHandler instanceof String) {
            String handlerName = (String) rawHandler;
            rawHandler = getApplicationContext().getBean(handlerName);
         }
         validateHandler(rawHandler, request);
         handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);
      }
   }
   if (handler != null && logger.isDebugEnabled()) {
      logger.debug("Mapping [" + lookupPath + "] to " + handler);
   }
   else if (handler == null && logger.isTraceEnabled()) {
      logger.trace("No handler mapping found for [" + lookupPath + "]");
   }
   return handler;
}

3.4 lookupHandler(lookupPath, request)根据给定url path和request获取Handler

protected Object lookupHandler(String urlPath, HttpServletRequest request) throws Exception {
   // Direct match?
   Object handler = this.handlerMap.get(urlPath);
   if (handler != null) {
      // Bean name or resolved handler?
      if (handler instanceof String) {
         String handlerName = (String) handler;
         handler = getApplicationContext().getBean(handlerName);
      }
      validateHandler(handler, request);
      return buildPathExposingHandler(handler, urlPath, urlPath, null);
   }
   // Pattern match?
   List matchingPatterns = new ArrayList();
   for (String registeredPattern : this.handlerMap.keySet()) {
      if (getPathMatcher().match(registeredPattern, urlPath)) {
         matchingPatterns.add(registeredPattern);
      }
   }
   String bestPatternMatch = null;
   Comparator patternComparator = getPathMatcher().getPatternComparator(urlPath);
   if (!matchingPatterns.isEmpty()) {
      Collections.sort(matchingPatterns, patternComparator);
      if (logger.isDebugEnabled()) {
         logger.debug("Matching patterns for request [" + urlPath + "] are " + matchingPatterns);
      }
      bestPatternMatch = matchingPatterns.get(0);
   }
   if (bestPatternMatch != null) {
      handler = this.handlerMap.get(bestPatternMatch);
      // Bean name or resolved handler?
      if (handler instanceof String) {
         String handlerName = (String) handler;
         handler = getApplicationContext().getBean(handlerName);
      }
      validateHandler(handler, request);
      String pathWithinMapping = getPathMatcher().extractPathWithinPattern(bestPatternMatch, urlPath);

      // There might be multiple best patterns, lets make sure we have the correct URI template variables
      // for all of them
      Map uriTemplateVariables = new LinkedHashMap();
      for (String matchingPattern : matchingPatterns) {
         if (patternComparator.compare(bestPatternMatch, matchingPattern) == 0) {
            uriTemplateVariables
                  .putAll(getPathMatcher().extractUriTemplateVariables(matchingPattern, urlPath));
         }
      }
      if (logger.isDebugEnabled()) {
         logger.debug("URI Template variables for request [" + urlPath + "] are " + uriTemplateVariables);
      }
      return buildPathExposingHandler(handler, bestPatternMatch, pathWithinMapping, uriTemplateVariables);
   }
   // No handler found...
   return null;
}

4.1 HandlerAdapter getHandlerAdapter(Object handler),根据Handler获取HandlerAdapter

/**
 * Return the HandlerAdapter for this handler object.
 * @param handler the handler object to find an adapter for
 * @throws ServletException if no HandlerAdapter can be found for the handler. This is a fatal error.
 */
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
   for (HandlerAdapter ha : this.handlerAdapters) {
      if (logger.isTraceEnabled()) {
         logger.trace("Testing handler adapter [" + ha + "]");
      }
      if (ha.supports(handler)) {
         return ha;
      }
   }
   throw new ServletException("No adapter for handler [" + handler +
         "]: Does your handler implement a supported interface like Controller?");
}

4.2 supports(Object handler)

public boolean supports(Object handler) {
   return (handler instanceof Controller);
}

5.1 使用处理器来完成请求的处理。

public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {

   ((Servlet) handler).service(request, response);
   return null;
}
public void service(ServletRequest req, ServletResponse res)
    throws ServletException, IOException
{
    HttpServletRequest  request;
    HttpServletResponse response;

    if (!(req instanceof HttpServletRequest &&
            res instanceof HttpServletResponse)) {
        throw new ServletException("non-HTTP request or response");
    }

    request = (HttpServletRequest) req;
    response = (HttpServletResponse) res;

    service(request, response);
}

5.2 service(HttpServletRequest req, HttpServletResponse resp)

protected void service(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException
{
    String method = req.getMethod();

    if (method.equals(METHOD_GET)) {
        long lastModified = getLastModified(req);
        if (lastModified == -1) {
            // servlet doesnt support if-modified-since, no reason
            // to go through further expensive logic
            doGet(req, resp);
        } else {
            long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
            if (ifModifiedSince < lastModified) {
                // If the servlet mod time is later, call doGet()
                // Round down to the nearest second for a proper compare
                // A ifModifiedSince of -1 will always be less
                maybeSetLastModified(resp, lastModified);
                doGet(req, resp);
            } else {
                resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
            }
        }

    } else if (method.equals(METHOD_HEAD)) {
        long lastModified = getLastModified(req);
        maybeSetLastModified(resp, lastModified);
        doHead(req, resp);

    } else if (method.equals(METHOD_POST)) {
        doPost(req, resp);

    } else if (method.equals(METHOD_PUT)) {
        doPut(req, resp);

    } else if (method.equals(METHOD_DELETE)) {
        doDelete(req, resp);

    } else if (method.equals(METHOD_OPTIONS)) {
        doOptions(req,resp);

    } else if (method.equals(METHOD_TRACE)) {
        doTrace(req,resp);

    } else {
        //
        // Note that this means NO servlet supports whatever
        // method was requested, anywhere on this server.
        //

        String errMsg = lStrings.getString("http.method_not_implemented");
        Object[] errArgs = new Object[1];
        errArgs[0] = method;
        errMsg = MessageFormat.format(errMsg, errArgs);

        resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
    }
}

5.3 doGet(HttpServletRequest req, HttpServletResponse resp)

protected void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException
{
    String protocol = req.getProtocol();
    String msg = lStrings.getString("http.method_get_not_supported");
    if (protocol.endsWith("1.1")) {
        resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
    } else {
        resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
    }
}

作者:CoderZS
链接:https://www.jianshu.com/p/8a20c547e245
资料来源:简讯
版权归作者所有。请联系作者以获得商业转载的授权,并注明非商业转载的来源。

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除

热门