• springmvc执行流程 源码分析


    浏览器发送一个请求给DispatcherServlet (在doDispatch(request, response)中);DispatcherServlet将请求交给HandleMapping 获取处理器执行链;DispatcherServlet获得执行链中的handle;遍历所有处理器适配器,获得支持handle的具体的适配器;处理器执行链执行前置处理(返回false就不再往下执行);然后由DispatcherServlet将请求、响应和handle交给处理器适配器处理,HandleAdapter执行控制器Controller中具体的方法返回ModelAndView;处理器执行链执行后置处理;通过试图解析器解析准确试图,将模型数组放到request域中渲染试图;将试图返回前端页面。

    HandlerMapping接口就一个作用:根据request获取handle和拦截器数组。


    概念理解:

    handler在这里,是指包含了我们请求的Controller类和 url映射的Method方法的对象。

    一个控制器Controller中有内部N个方法== N个Handler

    M个控制器=M×N个Handler

    M×N个Hanlder存放在handlerMappings中

     
     
    public interface HandlerMapping {
     HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
    }
    HandlerExecutionChain包含一个handle和一个拦截器数组。
    public class HandlerExecutionChain {
     private final Object handler;
     private HandlerInterceptor[] interceptors;
    ~
    }
    public class HttpRequestHandlerAdapter implements HandlerAdapter {
     @Override
     public boolean supports(Object handler) {
      return (handler instanceof HttpRequestHandler);
     }
     @Override
     public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
       throws Exception {
      ((HttpRequestHandler) handler).handleRequest(request, response);
      return null;
     }


    进入DispatcherServlet 执行onRefresh,然后执行初始化方法initStrategies。然后调用doService——>doDispatch。

    根据继承关系执行Servlet的步骤:

    init...............initStrategies

    service...........doService

    /**
         * This implementation calls {@link #initStrategies}.
         */
        @Override
        protected void onRefresh(ApplicationContext context) {
            initStrategies(context);
        }
    
        /**
         * Initialize the strategy objects that this servlet uses.
         * <p>May be overridden in subclasses in order to initialize further strategy objects.
         */
        protected void initStrategies(ApplicationContext context) {
            initMultipartResolver(context);
            initLocaleResolver(context);
            initThemeResolver(context);
            initHandlerMappings(context);
            initHandlerAdapters(context);
            initHandlerExceptionResolvers(context);
            initRequestToViewNameTranslator(context);
            initViewResolvers(context);
            initFlashMapManager(context);
        }
    /**
         * 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 resumed = WebAsyncUtils.getAsyncManager(request).hasConcurrentResult() ? " resumed" : "";
                logger.debug("DispatcherServlet with name '" + getServletName() + "'" + resumed +
                        " processing " + request.getMethod() + " request for [" + getRequestUri(request) + "]");
            }
    
            // Keep a snapshot of the request attributes in case of an include,
            // to be able to restore the original attributes after the include.
         // 保存request中的所有属性
    Map<String, Object> attributesSnapshot = null; if (WebUtils.isIncludeRequest(request)) { attributesSnapshot = new HashMap<String, Object>(); Enumeration<?> attrNames = request.getAttributeNames(); while (attrNames.hasMoreElements()) { String attrName = (String) attrNames.nextElement(); if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) { attributesSnapshot.put(attrName, request.getAttribute(attrName)); } } } // 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 { if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) { // Restore the original attribute snapshot, in case of an include. if (attributesSnapshot != null) { restoreAttributesAfterInclude(request, attributesSnapshot); } } } }
    /**
         * Process the actual dispatching to the handler.
         * <p>The handler will be obtained by applying the servlet's HandlerMappings in order.
         * The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters
         * to find the first that supports the handler class.
         * <p>All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers
         * themselves to decide which methods are acceptable.
         * @param request current HTTP request
         * @param response current HTTP response
         * @throws Exception in case of any kind of processing failure
         */
        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);
    
                    
              // 遍历handlerMappings获取HandlerExecutionChain实例(handle和HandlerInterceptor[])
    mappedHandler = getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } // Determine handler adapter for the current request.
              // 通过 处理器执行链 匹配 处理器适配器 实例
              // 获取 处理器执行链 HandlerExecutionChain中 handle,查找并返回支持handle的 处理器适配器HandlerAdapter 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()) { logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified); } if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; } }           //执行所有自定义的拦截器的preHandle(前置处理)方法 if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // Actually invoke the handler.
              // 执行handle返回ModelAndView实例
              // 使用匹配的 HandlerAdapter 处理请求
              // 此处将调用用户自定义的Controller类中的方法 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; } applyDefaultViewName(processedRequest, mv);
             //拦截器后置处理 mappedHandler.applyPostHandle(processedRequest, response, mv); }
    catch (Exception ex) { dispatchException = ex; } catch (Throwable err) { // As of 4.3, we're processing Errors thrown from handler methods as well, // making them available for @ExceptionHandler methods and other scenarios. dispatchException = new NestedServletException("Handler dispatch failed", err); } processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex); } catch (Throwable err) { triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", err)); } finally { if (asyncManager.isConcurrentHandlingStarted()) { // Instead of postHandle and afterCompletion if (mappedHandler != null) { mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); } } else { // Clean up any resources used by a multipart request. if (multipartRequestParsed) { cleanupMultipart(processedRequest); } } } }

    AbstractHandlerMapping的  getHandler方法,通过HandlerMapping获取处理器执行链:

    public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
            Object handler = getHandlerInternal(request);//获取hangdle
            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);
            }
         //添加拦截器
            HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
            if (CorsUtils.isCorsRequest(request)) {
                CorsConfiguration globalConfig = this.globalCorsConfigSource.getCorsConfiguration(request);
                CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
                CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
                executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
            }
            return executionChain;
        }
     protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
      HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
        (HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
    
    
        //根据request的url匹配所有拦截器,将拦截器放到处理器执行链中 
      String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
      for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
       if (interceptor instanceof MappedInterceptor) {
        MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
        if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
         chain.addInterceptor(mappedInterceptor.getInterceptor());
        }
       }
       else {
        chain.addInterceptor(interceptor);
       }
      }
      return chain;
     }
     
  • 相关阅读:
    vue 重定向
    vue 通过插槽分发内容
    vue 表单输入绑定 checkbox
    jq enter键发送
    vue footer点击变色
    vue computed和methods 计算属性和侦听器
    实时监听input输入情况
    关于Input输入框蓝色外框的操作
    鼠标悬浮指针变手
    鼠标悬浮样式
  • 原文地址:https://www.cnblogs.com/mryangbo/p/10757889.html
Copyright © 2020-2023  润新知