Spring MVC中DispatcherServlet理解总结(2)

请求处理流程

public class DispatcherServlet extends FrameworkServlet {

    public static final String WEB_APPLICATION_CONTEXT_ATTRIBUTE = DispatcherServlet.class.getName() + ".CONTEXT";
    public static final String LOCALE_RESOLVER_ATTRIBUTE = DispatcherServlet.class.getName() + ".LOCALE_RESOLVER";
    public static final String THEME_RESOLVER_ATTRIBUTE = DispatcherServlet.class.getName() + ".THEME_RESOLVER";
    public static final String THEME_SOURCE_ATTRIBUTE = DispatcherServlet.class.getName() + ".THEME_SOURCE";
    public static final String INPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".INPUT_FLASH_MAP";
    public static final String OUTPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".OUTPUT_FLASH_MAP";
    public static final String FLASH_MAP_MANAGER_ATTRIBUTE = DispatcherServlet.class.getName() + ".FLASH_MAP_MANAGER";
    public static final String EXCEPTION_ATTRIBUTE = DispatcherServlet.class.getName() + ".EXCEPTION";
    
    /**
     * requestUI预处理,设置默认属性
     */
    protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Map<String, Object> attributesSnapshot = null;
        if (WebUtils.isIncludeRequest(request)) {
           // 扩展阅读https://www.cnblogs.com/hzhuxin/p/4810347.html
        }
        request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.getWebApplicationContext());
        request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
        request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
        request.setAttribute(THEME_SOURCE_ATTRIBUTE, this.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 {
            // springMVC处理请求的核心
            this.doDispatch(request, response);
        } finally {
            if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted() && attributesSnapshot != null) {
                this.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 {
                // 检查request类型,判断http请求是否multipart/form-data类型
                processedRequest = this.checkMultipart(request);
                multipartRequestParsed = processedRequest != request;
                // 获取请求处理器,以及拦截器,以HandlerExecutionChain对象返回
                mappedHandler = this.getHandler(processedRequest);
                if (mappedHandler == null || mappedHandler.getHandler() == null) {
                    this.noHandlerFound(processedRequest, response);
                    return;
                }
                // 循环属性handlerAdapters列表,获取,获取支持处理器解析的HandlerAdapter。
                // 例如@Controller注解的对象,需要用AnnotationMethodHandlerAdapter实现来解析
                HandlerAdapter ha = this.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 (this.logger.isDebugEnabled()) {
                        this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
                    }

                    if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                        return;
                    }
                }
                
                // 调用HandlerExecutionChain中所有HandlerInterceptor拦截器的preHandle方法
                if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }
                
                // 根据请求url查找处理器(mappedHandler.getHandler())中符合要求的方法处理请求
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                if (asyncManager.isConcurrentHandlingStarted()) {
                    return;
                }
                
                // 如果返回的mv != null并且mv没有设置返回视图名称,则设置视图名称未viewNameTranslator的viewName属性
                this.applyDefaultViewName(processedRequest, mv);
                // 调用HandlerExecutionChain中所有HandlerInterceptor拦截器的postHandle方法
                mappedHandler.applyPostHandle(processedRequest, response, mv);
            } catch (Exception var19) {
                dispatchException = var19;
            }

            this.processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
        } catch (Exception var20) {
            // 调用HandlerExecutionChain中所有triggerAfterCompletion拦截器的afterCompletion方法
            this.triggerAfterCompletion(processedRequest, response, mappedHandler, var20);
        } catch (Error var21) {
            // 调用HandlerExecutionChain中所有triggerAfterCompletion拦截器的afterCompletion方法
            this.triggerAfterCompletionWithError(processedRequest, response, mappedHandler, var21);
        } finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                if (mappedHandler != null) {
                    // 调用HandlerExecutionChain中所有HandlerInterceptor拦截器的afterConcurrentHandlingStarted方法
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            } else if (multipartRequestParsed) {
                // 清除multipart请求占用的资源
                this.cleanupMultipart(processedRequest);
            }

        }

    }
    
    /**
     * HandlerExecutionChain相关属性
     *     Object handler :表现层处理器,例如用@Controller注解的对象
     *     List<HandlerInterceptor> interceptorList 拦截器链表
     **/
    protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        Iterator var2 = this.handlerMappings.iterator();
        HandlerExecutionChain handler;
        do {
            if (!var2.hasNext()) {
                return null;
            }
            HandlerMapping hm = (HandlerMapping)var2.next();
            // 根据请求的url,获取表现层处理器,同时返回拦截器列表
            handler = hm.getHandler(request);
        } while(handler == null);

        return handler;
    }
    
     /**
     * 处理返回结果
     **/
    private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception {
        boolean errorView = false;
        if (exception != null) {
            if (exception instanceof ModelAndViewDefiningException) {
                this.logger.debug("ModelAndViewDefiningException encountered", exception);
                mv = ((ModelAndViewDefiningException)exception).getModelAndView();
            } else {
                Object handler = mappedHandler != null ? mappedHandler.getHandler() : null;
                // 将异常处理交给handlerExceptionResolvers统一处理
                mv = this.processHandlerException(request, response, handler, exception);
                errorView = mv != null;
            }
        }

        if (mv != null && !mv.wasCleared()) {
            this.render(mv, request, response);
            if (errorView) {
                WebUtils.clearErrorRequestAttributes(request);
            }
        } else if (this.logger.isDebugEnabled()) {
            this.logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + this.getServletName() + "': assuming HandlerAdapter completed request handling");
        }

        if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
            if (mappedHandler != null) {
                // 调用HandlerExecutionChain中所有HandlerInterceptor拦截器的triggerAfterCompletion方法
                mappedHandler.triggerAfterCompletion(request, response, (Exception)null);
            }

        }
    }
    
}
复制代码

WebUtils.isIncludeRequest(request)作用:www.cnblogs.com/hzhuxin/p/4…

简单归纳

  • DispatcherServlet:前端控制器,接收发过来的请求(doDispatch(request, response))
  • HandlerMapping:循环DispatcherServletList<HandlerMapping>注册的处理映射器得到HandlerExecutionChain(HandlerExecutionChain HandlerExecutionChain getHandler(HttpServletRequest request))
    public interface HandlerMapping {
        ... 
        HandlerExecutionChain getHandler(HttpServletRequest var1) throws Exception;
    }
    public class HandlerExecutionChain {
        private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class);
        private final Object handler; # 表现层的Controller
        private HandlerInterceptor[] interceptors; # 拦截器
        private List<HandlerInterceptor> interceptorList;
        private int interceptorIndex;
    
        ...
    }
    复制代码
    • SimpleUrlHandlerMapping:通过配置请求路径和Controller映射建立关系,找到相应的Controller

      # Spring的配置文件
      <bean id="simpleControllerTest" class="com.jake.SimpleControllerTest"/>
      <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
          <property name="mappings">
              <props>
                  <prop key="/userlist.htm">simpleControllerTest</prop>
              </props>
          </property>
      </bean>
      # controller需要实现Controller
      public class SimpleControllerTest implements Controller {
          public ModelAndView handleRequest(HttpServletRequest request,
                  HttpServletResponse response) throws Exception {
              //do your things here...
              return new ModelAndView("homepage");
          }
      }
      # 访问方式
      http://ip:port/project/userlist.htm
      复制代码
    • ControllerClassNameHandlerMapping:通过 Controller 的类名找到请求的Controller

      # Spring的配置文件
      <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
      
      复制代码
    • BeanNameUrlHandlerMapping:通过定义的 beanName 进行查找要请求的Controller

      # Spring的配置文件
       <bean id="simpleController" name="/userlist.htm" class="com.jake.SimpleControllerTest"/>
       <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
       # controller需要实现Controller
      public class SimpleControllerTest implements Controller {
          public ModelAndView handleRequest(HttpServletRequest request,
                  HttpServletResponse response) throws Exception {
              //do your things here...
              return new ModelAndView("homepage");
          }
      }
      # 访问方式
      http://ip:port/project/userlist.htm
      复制代码
    • DefaultAnnotationHandlerMapping(已废弃):通过注解 @RequestMapping 来查找对应的Controller

    • RequestMappingHandlerMapping:替换DefaultAnnotationHandlerMapping

  • HandlerAdapter:循环DispatcherServletList<HandlerMapping>注册的处理器适配器,寻找可以执行当前请求的适配器HandlerAdapter ha = this.getHandlerAdapter(Object handler)
    public interface HandlerAdapter {
        # 判断当前适配器是否支持Controller的执行
        boolean supports(Object var1);
    
        ModelAndView handle(HttpServletRequest var1, HttpServletResponse var2, Object var3) throws Exception;
    
        long getLastModified(HttpServletRequest var1, Object var2);
    }
    复制代码
    • AnnotationMethodHandlerAdapter(已废弃):适配注解类处理器,即@Controller注解的这类处理器
    • HttpRequestHandlerAdapter:适配静态资源处理器,处理通过SpringMVC来访问的静态资源的请求
    • SimpleControllerHandlerAdapter:适配实现Controller接口或Controller接口子类的处理器
    • SimpleServletHandlerAdapter:适配实现了Servlet接口或Servlet的子类的处理器
    • RequestMappingHandlerAdapter:替换AnnotationMethodHandlerAdapter
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值