入口:

IMAGE

从 Tomcat 到 SpringMVC 的 DispatcherServlet

org.apache.catalina.core.StandardWrapperValve:

第一步: 获取 wrapper 容器

StandardWrapper wrapper = (StandardWrapper) getContainer();

第二步: 根据容器 wrapper 获取相应的 servlet

if (!unavailable) {
    servlet = wrapper.allocate();
}

第三步: 获取 filter 调用链

ApplicationFilterFactory 可以获取当前 Web 应用的所有 Filter 配置信息. 并以此来匹配相应的请求的 filter

ApplicationFilterChain filterChain = ApplicationFilterFactory.createFilterChain(request, wrapper, servlet)

第四步: 调用 filter

filterChain.doFilter(request.getRequest(), response.getResponse());

第五步: 根据调用链来执行当前的 filter

private void internalDoFilter(ServletRequest request, ServletResponse response){
    ...
    filter.doFilter(request, response, this);
    ...
}

IMAGE

可以看到, 当前有2个 filter ,然后它会按顺序, 从上到下依次执行相应的 filter

第六步: filter 执行完后, 就开始执行相应的 servlet 了.

servlet.service(request, response);

org.springframework.web.servlet.FrameworkServlet -> super.service(request, response); 因为一般来说, 只有 org.springframework.web.servlet.DispatcherServlet 继承了 FrameworkServlet , SpringMVC 就是通过 DispatcherServlet 来进行分发请求的(通过它的名字 DispatcherServlet 也可以大概知道它的字面意思, 调度器 servlet).

从 DispatcherServlet 到 Controller

第一步: 判断是不是 checkMultipart (即上传文件类型的 Request)

使用 org.springframework.web.multipart.commons.CommonsMultipartResolver 来判断.

如果 checkMultipart 返回的 HttpServletRequest 对象跟 doDispatch 方法中的 HttpServletRequest 对象引用不相等, 则表明是 MultipartHttpServletRequest 而不是普通的 HttpServletRequest .

第二步: 根据Request对象查找相应的 Handler

即根据请求的路径如 /hello 来查找相应的 Controller 及其方法对象, 以便要调用.

protected HandlerExecutionChain getHandler(HttpServletRequest request);

该方法是从 private List<HandlerMapping> handlerMappings; 对象中匹配.

查找 HandlerMethod

HandlerMapping.getHandler(request) ->

org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(HttpServletRequest request) ->

Object handler = getHandlerInternal(request);
protected HandlerMethod getHandlerInternal(HttpServletRequest request);

HandlerMethod 就是根据 url 匹配成功后返回的相应的方法对象.

->

String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);

成功后就返回该 handlerMehtod 对象了.

第三步: 根据 MethodHanlder 获取 HandlerExecutionChain , 即 handler 的调用链

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

        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;
    }

可以看到, 是根据相应的请求 URL 来获取相应的 Interceptor 拦截器, 并设置到调用链对象中.

例子这里只有2个 interceptor

IMAGE

注意, Inteceptor 还分区很多类型的. 例如有:

IMAGE

可以看到上面的源码, 如果是 MappedInterceptor 类型的, 它还要匹配该请求的 URL 是否满足该 Interceptor 的条件, 只有满足条件的, 才会将它加到该 Handler 的调用链中.

完成后, 可以看到调用链的对象已经设置好了

IMAGE

第四步: 获取 HandlerAdapter

默认情况下, 有三种 private List<HandlerAdapter> handlerAdapters;

IMAGE

第五步: 应用 interceptors

    boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HandlerInterceptor[] interceptors = getInterceptors();
        if (!ObjectUtils.isEmpty(interceptors)) {
            for (int i = 0; i < interceptors.length; i++) {
                HandlerInterceptor interceptor = interceptors[i];
                if (!interceptor.preHandle(request, response, this.handler)) {
                    triggerAfterCompletion(request, response, null);
                    return false;
                }
                this.interceptorIndex = i;
            }
        }
        return true;
    }

如果有返回 false 的, 表示中断了. 返回 true 表示继续向下执行.

第六步: 实际开始调用 Handler

protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod)

org.springframework.web.servlet.mvc.method.annotation.invokeHandlerMethod(...)

    protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
            HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

        ServletWebRequest webRequest = new ServletWebRequest(request, response);
        try {
            WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
            ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);

            ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
            invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
            invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
            invocableMethod.setDataBinderFactory(binderFactory);
            invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);

            ModelAndViewContainer mavContainer = new ModelAndViewContainer();
            mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
            modelFactory.initModel(webRequest, mavContainer, invocableMethod);
            mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);

            AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
            asyncWebRequest.setTimeout(this.asyncRequestTimeout);

            WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
            asyncManager.setTaskExecutor(this.taskExecutor);
            asyncManager.setAsyncWebRequest(asyncWebRequest);
            asyncManager.registerCallableInterceptors(this.callableInterceptors);
            asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);

            if (asyncManager.hasConcurrentResult()) {
                Object result = asyncManager.getConcurrentResult();
                mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
                asyncManager.clearConcurrentResult();
                if (logger.isDebugEnabled()) {
                    logger.debug("Found concurrent result value [" + result + "]");
                }
                invocableMethod = invocableMethod.wrapConcurrentResult(result);
            }

            invocableMethod.invokeAndHandle(webRequest, mavContainer);
            if (asyncManager.isConcurrentHandlingStarted()) {
                return null;
            }

            return getModelAndView(mavContainer, modelFactory, webRequest);
        }
        finally {
            webRequest.requestCompleted();
        }
    }
  1. 首先根据 hanlderMethod 获取 WebDataBinderFactory
  2. 再获取 ModelFactory
  3. 根据 HandlerMethod 构建 ServletInvocableHandlerMethod
  4. 然后为它们设置相应的处理器及属性

最后开始调用

invocableMethod.invokeAndHandle(webRequest, mavContainer);

    public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
            Object... providedArgs) throws Exception {

        Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
        setResponseStatus(webRequest);

        if (returnValue == null) {
            if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
                mavContainer.setRequestHandled(true);
                return;
            }
        }
        else if (StringUtils.hasText(getResponseStatusReason())) {
            mavContainer.setRequestHandled(true);
            return;
        }

        mavContainer.setRequestHandled(false);
        try {
            this.returnValueHandlers.handleReturnValue(
                    returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
        }
        catch (Exception ex) {
            if (logger.isTraceEnabled()) {
                logger.trace(getReturnValueHandlingErrorMessage("Error handling return value", returnValue), ex);
            }
            throw ex;
        }
    }

可以看到该方法的第一行 Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);

这就是真正调用 HandlerMethod 来处理请求了.

    public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer,
            Object... providedArgs) throws Exception {

        Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
        if (logger.isTraceEnabled()) {
            logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
                    "' with arguments " + Arrays.toString(args));
        }
        Object returnValue = doInvoke(args);
        if (logger.isTraceEnabled()) {
            logger.trace("Method [" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
                    "] returned [" + returnValue + "]");
        }
        return returnValue;
    }

invokeForRequest 的第一行 getMethodArgumentValues, 这里就是构建的们的 Controller 对应的方法的参数了. 所有参数的自动处理, 就是在这里进行的.处理完后, 就会根据这些参数来正式调用该 Controller 的方法了.

getMethodArgumentValues 处理:

根据所注册的 argumentResolvers 来判断当前位置的参数, 是否被相应的 argumentResolvers 所支持解析. 如果匹配的话, 则会调用它来进行参数解析.

最终会调用 ServletRequestMethodArgumentResolver.resolveArgument() 方法来解析参数.

所有的参数如果都正确的解析完后, 就会真正调用我们自己的 Controller 的相应的方法了.

IMAGE