运行helloWorld示例进入调试界面。
DispatcherServlet:前端控制器
DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse) line: 945 DispatcherServlet.doService(HttpServletRequest, HttpServletResponse) line: 876 DispatcherServlet(FrameworkServlet).processRequest(HttpServletRequest, HttpServletResponse) line: 931 DispatcherServlet(FrameworkServlet).doGet(HttpServletRequest, HttpServletResponse) line: 822 DispatcherServlet(HttpServlet).service(HttpServletRequest, HttpServletResponse) line: 624 DispatcherServlet(FrameworkServlet).service(HttpServletRequest, HttpServletResponse) line: 807 DispatcherServlet(HttpServlet).service(ServletRequest, ServletResponse) line: 731
由上进入源码查看
DispatcherServlet(FrameworkServlet).service(HttpServletRequest, HttpServletResponse) line: 807的
public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware { ... service(); }
HttpServletBean 的实现
public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware {}
接下来重点关注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; // Determine handler for the current request. //1、根据当前请求地址找到哪个处理器来处理请求 mappedHandler = getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { //2、如果找不到报错 noHandlerFound(processedRequest, response); return; } // Determine handler adapter for the current request. //2\为当前请求确定适配器 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()) { String requestUri = urlPathHelper.getRequestUri(request); logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified); } if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; } } if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } try { // Actually invoke the handler. //真正执行方法 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); } finally { if (asyncManager.isConcurrentHandlingStarted()) { return; } } applyDefaultViewName(request, 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 mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); return; } // Clean up any resources used by a multipart request. if (multipartRequestParsed) { cleanupMultipart(processedRequest); } } }
四步:
1)、所有请求进来都经过DispatcherServlet的900:doDispatch()方法(包含了处理请求以及响应的所有流程)
2)、916;getHandler(processedRequest);根据当前请求获取到能处理这个请求的Controller对象
3)、923:找到能执行这个Controller对象里面每一个方法的适配器
4)、945:ha.handle适配器调用目标方法(利用反射调用方法)
5)、959:转发到页面(处理响应结果)processDispatchResult
1、根据当前请求地址找到哪个处理器来处理请求 mappedHandler = getHandler(processedRequest);
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { for (HandlerMapping hm : this.handlerMappings) { if (logger.isTraceEnabled()) { logger.trace( "Testing handler map [" + hm + "] in DispatcherServlet with name ‘" + getServletName() + "‘"); } HandlerExecutionChain handler = hm.getHandler(request); if (handler != null) { return handler; } } return null; }
SpringfMVC启动的时候扫描所有的注解,将每一个类的每一个方法能处理什么请求都已经保存在handlerMapping中了;DefaultAnnotationHandlerMapping;
2、为当前请求确定适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
找到能调用这个类里面每个方法的适配器;适配器利用反射调用方法;
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { for (HandlerAdapter ha : this.handlerAdapters) { if (logger.isTraceEnabled()) { logger.trace("Testing handler adapter [" + ha + "]"); } if (ha.supports(handler)) { return ha; } } throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler"); }
我们都使用注解模式的所以适配器使用第三个;
3、SpringMVC中DispatcherServlet的几个重要属性,以及赋值
SpringMVC九大组件;
/** 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; /** List of HandlerAdapters used by this servlet适配器;用来执行控制器(处理器)目标方法的*/ private List<HandlerAdapter> handlerAdapters; /** List of HandlerExceptionResolvers used by this servlet 异常解析器*/ private List<HandlerExceptionResolver> handlerExceptionResolvers; /** RequestToViewNameTranslator used by this servlet 转化器*/ private RequestToViewNameTranslator viewNameTranslator; /** FlashMapManager used by this servletFlashMap 管理器 */ private FlashMapManager flashMapManager; /** List of ViewResolvers used by this servlet视图解析器 */ private List<ViewResolver> viewResolvers;
文件上传组件默认没值;
默认赋值;
protected void initStrategies(ApplicationContext context) {
//默认从ioc容器中获取id为multipartResolver的组件,如果没有获取到就赋值为null;
initMultipartResolver(context);
//按照id获取localeResolver;如果没有;
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
//1、有些组件是这么》?先获取用户配置的,如果没有可以使用默认的(MultipartResolver )
//2、有些组件是拿id获取的;有些是拿类型获取的,
//3、给SpringMVC中配置九大之一的某个组件;如果是拿id‘获取的?id不要乱写,用指定id;
//如果是用类型获取,id可以不用写;
在于DispatcherServlet.class同目录下有一个properties文件,这里封装了所有组件默认的类型;