类关系java
DispatcherServlet 继承 FrameworkServlet 继承 HttpServletBean,HttpServletBean 是一个HttpServlet和EnvironmentCapable, EnvironmentAware接口的实现。web
本章关注点在DispatcherServlet对请求的分派调用流程上,这些类暂不关注。spring
成员变量json
一、静态变量主要是一些bean名称,以及request attribute 的key。如app
/** Well-known name for the MultipartResolver object in the bean factory for this namespace. */ public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver"; /** Well-known name for the LocaleResolver object in the bean factory for this namespace. */ public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver"; /** Well-known name for the ThemeResolver object in the bean factory for this namespace. */ public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver";
二、具体的特殊的bean,上一章中提到的特殊bean。如async
/** MultipartResolver used by this servlet */ private MultipartResolver multipartResolver; /** LocaleResolver used by this servlet */ private LocaleResolver localeResolver; /** ThemeResolver used by this servlet */ private ThemeResolver themeResolver; /** List of HandlerMappings used by this servlet */ private List<HandlerMapping> handlerMappings;
方法ide
方法重点关注doService,doDispatch这两个方法,其余的方法是get/set 和初始化方法,不是本章的关注对象。下面的这两个方法源码和注释。post
//重写HttpServlet 的请求处理方法 @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. //保留一个原请求属性的备份。 Map<String, Object> attributesSnapshot = null; if (WebUtils.isIncludeRequest(request)) { //是内部发出的请求 forward attributesSnapshot = new HashMap<String, Object>(); Enumeration<?> attrNames = request.getAttributeNames(); while (attrNames.hasMoreElements()) { String attrName = (String) attrNames.nextElement(); //若是是DispatcherServlet cleanupAfterInclude(是include 请求就清理)属性为true,或者request的属性是DispatcherServlet附加的,保存备份 if (this.cleanupAfterInclude || attrName.startsWith("org.springframework.web.servlet")) { attributesSnapshot.put(attrName, request.getAttribute(attrName)); } } } //附加webApplicationContext 的特殊bean // Make framework objects available to handlers and view objects. //web application context 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 { //分派到handler,进行业务逻辑处理 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); } } } } 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 { //检查是否 multipart request processedRequest = checkMultipart(request); //request 不等于 processedRequest 表示检查到multi ,并构建返回 multi request multipartRequestParsed = (processedRequest != request); // Determine handler for the current request. //决定、判断、获取 handler mappedHandler = getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { //找不到相应的handler ,返回并提示 noHandlerFound noHandlerFound(processedRequest, response); return; } // Determine handler adapter for the current request. //查找handler 的适配器(不一样的方法细节多样、参数等,经过adapter 封装) HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // Process last-modified header, if supported by the handler. //判断是否支持last-modified 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; } } //执行前拦截器 if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // Actually invoke the handler. //调用实际业务方法逻辑 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; } //解析modelview 中的名称映射对应的视图模板。 applyDefaultViewName(processedRequest, mv); //执行后拦截器 mappedHandler.applyPostHandle(processedRequest, response, mv); } catch (Exception ex) { dispatchException = ex; } //处理执行的结果,异常的话,跳转处理异常的代码。 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex); } catch (Error err) { triggerAfterCompletionWithError(processedRequest, response, mappedHandler, 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); } } } }
注释不正确的地方,请指出。this
从源码咱们能够看出,基本上请求的出来流程正如第一篇中所描述的。spa
第一步是绑定各类各样的web context bean。
第二步是搜索获取对应请求的处理handler,以及对应的adapter。
第三步是执行找出的handler,前拦截器,handler, 后拦截器。
第四步是将结果或异常进行处理,如将string 映射到具体的view 或者输出json等。捕获异常的调用Exception handler 处理。