SpringMVC执行过程及源码分析
一、SpringMVC常用组件
-
DispatcherServlet:前端控制器
统一处理请求和响应,整个流程控制的中心,由它来调度下述的六个组件相互配合来处理请求
-
HandlerMapping:处理器映射器
根据请求的url、method等信息匹配到相应的Hander(Controller)- - 控制方法
-
Handler:处理器
根据具体的请求进行对应的处理
-
HandlerAdapter:处理器适配器
用于调用执行控制方法
-
ViewResolver:视图解析器
进行视图解析,得到相应的视图,如Thymeleaf(无前缀的视图名称),InternalResourceView(forword.开头的视图名称)、RedirectView(redirect.开头的视图名称)
-
View:视图
由视图解析器解析视图名称后得到的视图,将模型数据通过页面展示给用户
二、DispatcherServlet的初始化策略 - init
-
DispatcherServlet类的继承实现路径
-
DispatcherServlet类初始化过程
-
源码解析
注:只展示源码中的关键代码,用来梳理逻辑,故有删减
// 1.Servlet public interface Servlet { void init(ServletConfig var1) throws ServletException; } // 2.GenericServlet public void init(ServletConfig config) throws ServletException { this.config = config; this.init(); } public void init() throws ServletException { } // 3.HttpServlet:无init方法 // 4.HttpServletBean @Override public final void init() throws ServletException { initServletBean(); } protected void initServletBean() throws ServletException { } /* 5.FrameworkServlet 对springMVC进行IOC初始化的过程,核心方法initWebApplicationContext ① 创建webApplicationContext对象 ② 进行刷新,初始化DispatcherServlet要进行调度的各组件 ③ 将wac(webApplicationContext对象)共享到application应用作用域 */ // 属性 @Nullable private WebApplicationContext webApplicationContext; // 方法 @Override protected final void initServletBean() throws ServletException { /* ApplicationContext,是BeanFactory接口的子接口,用于实现IOC容器 ① 如果是Java环境,就使用ApplicationContext ② 如果是Web环境,就使用WebApplicationContext 所以,initWebApplicationContext就是对springMVC进行IOC容器初始化 */ this.webApplicationContext = initWebApplicationContext(); } // 对springMVC进行IOC容器初始化 protected WebApplicationContext initWebApplicationContext() { WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); WebApplicationContext wac = null; // 5.1 该方法第一次执行时,webApplicationContext肯定为空 if (this.webApplicationContext != null) { wac = this.webApplicationContext; } // 5.2 wac为空,寻找webApplicationContext,但是找不到 if (wac == null) { wac = findWebApplicationContext(); } // 5.3 wac为空,创建webApplicationContext if (wac == null) { wac = createWebApplicationContext(rootContext); } // 5.4 初始化DispatcherServlet要进行调度的各组件 if (!this.refreshEventReceived) { synchronized (this.onRefreshMonitor) { onRefresh(wac); } } // 5.5 将wac共享到应用作用域 if (this.publishContext) { // 查看对应5.5的内容,获取ServletContext的全类名 String attrName = getServletContextAttributeName(); // 将wac共享到了Application应用作用域 getServletContext().setAttribute(attrName, wac); } return wac; } // 对应5.3 protected WebApplicationContext createWebApplicationContext(@Nullable WebApplicationContext parent) { return createWebApplicationContext((ApplicationContext) parent); } // createWebApplicationContext的重载方法 protected WebApplicationContext createWebApplicationContext(@Nullable ApplicationContext parent) { Class<?> contextClass = getContextClass(); // 利用反射创建wac的多态对象 ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass); // 设置环境 wac.setEnvironment(getEnvironment()); // 设置父容器 wac.setParent(parent); return wac; } // 对应5.4 protected void onRefresh(ApplicationContext context) { // 在子类中实现 } // 对应5.5 public String getServletContextAttributeName() { return SERVLET_CONTEXT_PREFIX + getServletName(); } // 5.5.1 SERVLET_CONTEXT_PREFIX:属性,前缀 public static final String SERVLET_CONTEXT_PREFIX = FrameworkServlet.class.getName() + ".CONTEXT."; // 5.5.2 getServletName方法 @Override public String getServletName() { return (getServletConfig() != null ? getServletConfig().getServletName() : null); } public ServletConfig getServletConfig() { // config是属性 :private transient ServletConfig config; return this.config; } // 6.DispatcherServlet @Override protected void onRefresh(ApplicationContext context) { initStrategies(context); } /* 在initStrategies方法内调用各组件的初始化方法 故要在web.xml内设置,将DispatcherServlet的初始化提前到服务器初始化时 */ protected void initStrategies(ApplicationContext context) { // 初始化文件上传解析器 initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); // 初始化处理器映射器 initHandlerMappings(context); // 初始化处理器适配器 initHandlerAdapters(context); // 初始化处理器异常处理器 initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); // 初始化视图解析器 initViewResolvers(context); initFlashMapManager(context); }
三、DispatcherServlet调度各组件处理请求 - service
-
service方法的执行过程
-
源码分析
// 1.Servlet void service(ServletRequest var1, ServletResponse var2) ; // 2.GenericServlet public abstract void service(ServletRequest var1, ServletResponse var2); // 3.HttpServlet public void service(ServletRequest req, ServletResponse res) { // 将 ServletRequest 强制转换为 HttpServletRequest if (req instanceof HttpServletRequest && res instanceof HttpServletResponse) { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)res; this.service(request, response); } } protected void service(HttpServletRequest req, HttpServletResponse resp) { String method = req.getMethod(); if (method.equals("GET")) { this.doGet(req, resp); } else if (method.equals("HEAD")) { this.doHead(req, resp); } else if (method.equals("POST")) { this.doPost(req, resp); } else if (method.equals("PUT")) { this.doPut(req, resp); } else if (method.equals("DELETE")) { this.doDelete(req, resp); } else if (method.equals("OPTIONS")) { this.doOptions(req, resp); } else if (method.equals("TRACE")) { this.doTrace(req, resp); } } // 4.HttpServletBean:无service方法 // 5.FrameworkServlet @Override protected void service(HttpServletRequest request, HttpServletResponse response){ HttpMethod httpMethod = HttpMethod.resolve(request.getMethod()); if (httpMethod == HttpMethod.PATCH || httpMethod == null) { processRequest(request, response); } else { // 调用父类中的service super.service(request, response); } } @Override protected final void doGet(HttpServletRequest request, HttpServletResponse response) { processRequest(request, response); } protected final void processRequest(HttpServletRequest request, HttpServletResponse response) { // 这是一个抽象方法,在子类DispatcherServlet中重写 doService(request, response); } // 该方法核心方法,即核心方法在DispatcherServlet类中 protected abstract void doService(HttpServletRequest request, HttpServletResponse response); // 6.DispatcherServlet @Override protected void doService(HttpServletRequest request, HttpServletResponse response){ // 该方法s处理请求方法的核心方法 doDispatch(request, response); }
-
重点解析doDispatcher方法
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { // 1.重新创建一个请求变量,将传来的请求赋值给该新变量 HttpServletRequest processedRequest = request; /* 2.创建一个HandlerExecutionChain执行链对象 该对象用于调用拦截器的三个方法(preHandle、postHandle、afterCompletion),及通过 处理器映射器匹配到的控制方法 */ HandlerExecutionChain mappedHandler = null; boolean multipartRequestParsed = false; WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try { // 3.创建ModelAndView对象 ModelAndView mv = null; Exception dispatchException = null; try { processedRequest = checkMultipart(request); multipartRequestParsed = (processedRequest != request); /* 2.1 mappedHandler对象包含三个参数内容 ① handler:控制方法 ② interceptorList:拦截器列表 ③ interceptorIndex:拦截器索引,指明当前使用的拦截器 即处理器映射器解析URL后,将匹配到的Handler对象以及对应的拦截器以 HandlerExecutionChain执行链对象的方式返回 */ mappedHandler = getHandler(processedRequest); if (mappedHandler == null) { noHandlerFound(processedRequest, response); return; } // 4.创建处理器适配器对象ha HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); 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; } } // 2.2 执行拦截器的preHandle方法 if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } /* 5.调用控制器方法,返回一个ModuleAndView对象,在此过程中做了很多事情,包含 收集请求参数、获取请求头信息、cookie、请求体、数据类型转换(传送过来的是 String,就可以用Integer类型接收了) */ mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; } applyDefaultViewName(processedRequest, mv); // 2.3 执行拦截器的postHandle方法 mappedHandler.applyPostHandle(processedRequest, response, mv); } catch (Exception ex) { dispatchException = ex; } // 6.对控制方法的返回结果mv进行处理 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex); } finally { // 伪代码 } } // 第6步源码解析 private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception { boolean errorView = false; // 有异常执行该程序块 if (exception != null) { // 伪代码 } // 渲染视图 if (mv != null && !mv.wasCleared()) { // 调用render方法进行视图渲染 render(mv, request, response); } if (mappedHandler != null) { // 调用拦截器的AfterCompletion方法 mappedHandler.triggerAfterCompletion(request, response, null); } } // 第2步源码解析 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; }