SpringMVC的执行流程
1) 用户向服务器发送请求,请求被SpringMVC前端控制器DispatcherServlet捕获 2) DispatcherServlet对请求URL进行解析,得到请求资源标识符URI,判断请求URI对应的映射: A) 不存在 I) 再判断是否配置了mvc:default-servlet-handler II) 如果没有配置,则在控制台报映射查找不到,客户端展示404错误 III) 如果有配置,则访问目标资源(一般为静态资源:JS,CSS,HTML)。找不到资源客户端也会展示404错误; IV) B) 存在则执行下面的流程 3) 根据该URI,调用HandlerMapping获得该Handler配置的所有相关对象(Handler对象以及Handler对象对应的拦截器),最后以HandlerExcutionChain执行链对象的形式返回。 4) DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter; 5) 如果成功获得HandlerAdapter,此时将开始执行拦截器的preHandler; 6) 提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)方法,处理请求。在填充Handler的入参过程中,根据你的配置,Spring将帮助你做一些额外的工作; a) HttpMessageConveter:将请求(json,xml)装换成一个对象,将对象转换为指定的响应信息; b) 数据转换:对请求新进行数据转换。如String转换成Integer,Double等 c) 数据格式化:对请求信息进行数据格式化。如字符串转换格式化数字或者格式化日期等; d) 数据验证:验证数据的有效性(长度,格式等),验证结果存储到BindingResult或者Error中 7) Handler执行完成后,向 DispatcherServlet 返回一个ModelAndView对象 8) 此时开始执行拦截器的postHandle 9) 根据返回的ModelAndView选择一个合适的ViewResolver进行视图解析,根据Model和View来渲染视图; 渲染视图完毕执行拦截器的afterCompletion 将渲染结果返回给客户端‘
DispatcherServlet的初始化过程
DispatcherServlet本质上是一个Servlet,所有天然的遵循Servlet的生命周期。所有宏观上是Servlet生命周期来进行调度。 DispatcherServlet --> FrameworkServlet – > HttpServletBean – > HttpServlet – > GenericServlet – > Servlet
GenericServlet::init(ServletConfig) -> HttpServletBean::init() -> FrameworkServlet::initServletBean():
- FrameworkServlet::initWebApplicationContext()
FrameworkServlet::createWebApplicationContext()-> DispatcherServlet::onRefresh() -> DispatcherServlet::initStrategies: 初始化DispatcherServlet的各个组件(组件扫描、视图解析器、view-controller、default-servlet-handler、拦截器、异常处理、注解驱动、文件上传解析器) 将创建的 applicationcontext 共享到 Servlet全局域中(ServletContext(attrname:value))
DispatcherServlet调用组件处理请求
HttpServlet::service(ServletRequest req, ServletResponse resp) -> FrameworkServlet::service(HttpServletRequest, HttpServletResponse) -> 如果method是PATCH或者为null则调用 processRequest(); 否则调用HttpServlet::service(HttpServletRequest, HttpServletResponse) -> FrameworkServlet::doPost/doGet(HttpServletRequest request, HttpServletResponse response) -> processRequest() ->DispatcherServlet::doService(request, response) -> 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. //这里包含了 我们实现的Handler、Interceptors mappedHandler = getHandler(processedRequest); if (mappedHandler == null) { noHandlerFound(processedRequest, response); return; } // Determine handler adapter for the current request. 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; } } //调用拦截器的preHandle 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); } catch (Exception ex) { dispatchException = ex; } catch (Throwable err) { // As of 4.3, we’re processing Errors thrown from handler methods as well, // making them available for @ExceptionHandler methods and other scenarios. dispatchException = new NestedServletException(“Handler dispatch failed”, err); } processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex); } catch (Throwable err) { triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException(“Handler processing failed”, 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); } } } }
|