关于spring-mvc:DispatchServlet源码解析

38次阅读

共计 5034 个字符,预计需要花费 13 分钟才能阅读完成。

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 {processedRequest = checkMultipart(request);
                multipartRequestParsed = (processedRequest != request);

                // 为以后申请匹配处理器(HandlerExecutionChain)mappedHandler = getHandler(processedRequest);
                if (mappedHandler == null) {noHandlerFound(processedRequest, response);
                    return;
                }

                // 为以后申请匹配 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 (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {return;}
                }

                if (!mappedHandler.applyPreHandle(processedRequest, response)) {return;}

                // Actually invoke the handler.
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

                if (asyncManager.isConcurrentHandlingStarted()) {return;}

                applyDefaultViewName(processedRequest, mv);
                mappedHandler.applyPostHandle(processedRequest, response, mv);
            }
            
            ...

            
            processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
        }
        
        ...
    }

HandlerExecutionChain.class

处理器实质上蕴含了 HandleMethod 和 HandlerInterceptor 的执行链

public class HandlerExecutionChain {

    // 此处的 handler 通常为 HandleMethod
    private final Object handler;

    @Nullable
    private HandlerInterceptor[] interceptors;

    @Nullable
    private List<HandlerInterceptor> interceptorList;

    private int interceptorIndex = -1;
}

getHandler()

该办法遍历 handlerMappings,匹配对应的 HandlerMapping 结构 HandlerExecutionChain

    @Nullable
    private List<HandlerMapping> handlerMappings;

    @Nullable
    protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {if (this.handlerMappings != null) {for (HandlerMapping mapping : this.handlerMappings) {HandlerExecutionChain handler = mapping.getHandler(request);
                if (handler != null) {return handler;}
            }
        }
        return null;
    }

HandlerMapping 接口,决定申请与相应处理器(HandlerExecutionChain)的映射关系

public interface HandlerMapping {
    @Nullable
    HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;

}

HandlerMapping 的常见实现类有

getHandlerAdapter 办法

持续看回 doDispatch 办法中通过 handler 获取 handlerAdapter 的实现

    @Nullable
    private List<HandlerAdapter> handlerAdapters;

    protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {if (this.handlerAdapters != null) {for (HandlerAdapter adapter : this.handlerAdapters) {if (adapter.supports(handler)) {return adapter;}
            }
        }
    }

HandlerAdapter 接口

public interface HandlerAdapter {
    // 判断以后适配器是否反对该处理器
    boolean supports(Object handler);

    // 解决申请,返回 ModelAndView
    @Nullable
    ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

    long getLastModified(HttpServletRequest request, Object handler);
}

常见实现类

其中 RequestMappingHandlerAdapter#handle 的实现

ServletWebRequest webRequest = new ServletWebRequest(request, response);
        try {WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
            ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
            // 将 HandlerMethod 转化为 ServletInvocableHandlerMethod
            ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
            if (this.argumentResolvers != null) {invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
            }
            if (this.returnValueHandlers != null) {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();
                LogFormatUtils.traceDebug(logger, traceOn -> {String formatted = LogFormatUtils.formatValue(result, !traceOn);
                    return "Resume with async result [" + formatted + "]";
                });
                invocableMethod = invocableMethod.wrapConcurrentResult(result);
            }
            // 最终执行 invokeAndHandle
            invocableMethod.invokeAndHandle(webRequest, mavContainer);
            if (asyncManager.isConcurrentHandlingStarted()) {return null;}

            return getModelAndView(mavContainer, modelFactory, webRequest);
        }
        finally {webRequest.requestCompleted();
        }

正文完
 0