DispatcherServlet解析

概述

DispatcherServlet继承自HttpServlet类,是spring mvc对servlet的具体实现。而最关键的实现代码就在doDispatch方法中。先看看doDispatch的具体实现

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 {
                //1检查是否Multipart请求(文件上传),如果是,调用MultipartResolver.resolveMultipart(HttpServletRequest)解析Multipart资源,返回一个适配类MultipartHttpServletRequest,否则返回参数中的request。
                processedRequest = checkMultipart(request);
                multipartRequestParsed = (processedRequest != request);

                // 2.根据url获取一个具体的HanderMapper对象,让后封装成HandlerExecutionChain对象。
                mappedHandler = getHandler(processedRequest);
                if (mappedHandler == null || mappedHandler.getHandler() == null) {
                    noHandlerFound(processedRequest, response);
                    return;
                }

                // 3.根据handler找到对应的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;
                    }
                }
               //4调用拦截器的 preHandle 方法
                if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }

                // 5调用具体的接口方法,并返回模型视图对象
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

                if (asyncManager.isConcurrentHandlingStarted()) {
                    return;
                }
               //6.调用拦截器postHandle方法
                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);
            }
            //7调用processDispatchResult方法处理Handler处理之后的结果
            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);
                }
            }
        }
    }

MultipartResolver

checkMultipart调用multipartResolver.resolveMultipart(request)解析Multipart资源,实际上这个方法返回了一个MultipartHttpServletRequest接口的实现对象,MultipartHttpServletRequest接口继承了HttpServletRequest和MultipartRequest,获取文件的操作都在MultipartRequest中定义。其中MultipartResolver默认有两个实现类,分别是CommonsMultipartResolver和StandardServletMultipartResolver

protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
    if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
        if (WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class) != null) {
            logger.debug("Request is already a MultipartHttpServletRequest - if not in a forward, " +
                    "this typically results from an additional MultipartFilter in web.xml");
        }
        else if (request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) instanceof MultipartException) {
            logger.debug("Multipart resolution failed for current request before - " +
                    "skipping re-resolution for undisturbed error rendering");
        }
        else {
            //解析
            return this.multipartResolver.resolveMultipart(request);
        }
    }
    // If not returned before: return original request.
    return request;
}

获取HandlerExecutionChain

HandlerExecutionChain只能通过HanderMapping接口中的唯一方法来获得,HandlerMapping实例对象的getHandler方法可以获得一个HandlerExecutionChain对象实例,该实例封装了一个handler处理对象和一些interceptors。

Object handler;不做过多介绍,存储的对象是HandlerMethod
HandlerInterceptor[] interceptors :所有的HandlerInterceptor的数组
List<HandlerInterceptor> interceptorList:所有的HandlerInterceptor的链表

HandlerMapping 是由 DispatcherServlet 调用,DispatcherServlet 会从容器中取出所有 HandlerMapping 实例并遍历,让 HandlerMapping 实例根据自己实现类的方式去尝试查找 Handler

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
    // 这些 HandlerMapping 在容器初始化时创建,在 initHandlerMappings 时放入集合中
    for (HandlerMapping hm : this.handlerMappings) {
        HandlerExecutionChain handler = hm.getHandler(request);
        if (handler != null) {
            return handler;
        }
    }
    return null;
}

HandlerMapping

HanderMapping接口定义如下

我们可以在应用中使用预先构建的或者提供好的HandlerMapping的任何实现类,用来控制请求到处理对象之间的路由的。默认的实现类是:org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping和org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.
HanderMapping接口定义如下:

public interface HandlerMapping {
    String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE = HandlerMapping.class.getName() + ".pathWithinHandlerMapping";
    String BEST_MATCHING_PATTERN_ATTRIBUTE = HandlerMapping.class.getName() + ".bestMatchingPattern";
    String INTROSPECT_TYPE_LEVEL_MAPPING = HandlerMapping.class.getName() + ".introspectTypeLevelMapping";
    String URI_TEMPLATE_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".uriTemplateVariables";
    String MATRIX_VARIABLES_ATTRIBUTE = HandlerMapping.class.getName() + ".matrixVariables";
    String PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE = HandlerMapping.class.getName() + ".producibleMediaTypes";
  
    //该方法是HandlerMapping接口中的唯一方法,此方法可以利用用户请求request中的信息来生成HandlerExecutionChain对象
    HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
 
}

HandlerMethod

HandlerMethod其实可以简单理解为保持方法信息的pojo.就springMVC的Controller来说就是某个url对应的某个Controller执行的方法。
定义如下

package org.springframework.web.method;
public class HandlerMethod {
    protected final Log logger = LogFactory.getLog(HandlerMethod.class);
    // 方法所在的类,如果是String类型,可以去容器中获取
    private final Object bean;
    // 方法
    private final Method method;
    // 类管理的容器
    private final BeanFactory beanFactory;
    // 方法的参数
    private final MethodParameter[] parameters;
    // 如果方法是bridged方法,则对应原始方法
    private final Method bridgedMethod;
    // ...
}

Interceptor 拦截器

HandlerInterceptor接口

在preHandler阶段,要遍历执行所有的HandlerInterceptor ,执行preHandle。
拦截器的总接口 HandlerInterceptor 定义如下:

public interface HandlerInterceptor {
  boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
     
  void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception;
 
  void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception;
}

HandlerIntercetor共有13个实现类.

HandlerAdapter

根据 Handler 来找到支持它的 HandlerAdapter,通过 HandlerAdapter 执行这个 Handler 得到 ModelAndView 对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值