Spring MVC Basic Process Flow
来源:互联网 发布:做测试用linux干什么 编辑:程序博客网 时间:2024/06/06 03:46
Spring MVC Basic Process Flow
1. Spring MVC Basic Framwork
2. DispatcherServlet Source Code
DispatcherServlet继承自HttpServlet,所以入口为 doService 方法:
@Override protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception { // ... // 设置 DispatcherServlet.properties 配置的默认处理器映射器、适配器等. 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 { // 调用核心方法 doDispatch(request, response) 进行组件的分派 doDispatch(request, response); } // ... }
重点分析doDispatch(request, response)
方法,主要包含以下步骤:
- 调用处理器映射器,根据请求的url查找处理的Handler,返回HandlerChain;
- 调用处理器适配器执行Handler,返回ModelAndView;
- 请求进行视图(ViewResolver)解析;
- 根据返回的View进行视图渲染;
- response;
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); // 1. 根据请求的url返回映射的Handler:Determine handler for the current request. mappedHandler = getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } // 2. 根据获取的Handler得到HandlerAdapter:Determine handler adapter for the current request. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // Process last-modified header, if supported by the handler. // 3. 执行Handler获取模型视图对象ModelAndView: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; } // 4. 根据返回的view进行视图渲染,将模型数据填充到request域 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); } } } }
1. 根据请求的url返回映射的Handler
DispatcherServlet中的getHandler(request)方法:
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() + "'"); } // 处理器映射器HandlerMapping(其实就是一个Map集合)获取对应的HandlerChain HandlerExecutionChain handler = hm.getHandler(request); if (handler != null) { return handler; } } return null; }
2. 根据获取的Handler得到HandlerAdapter
DispatcherServlet中的getHandlerAdapter(handler)方法:
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { for (HandlerAdapter ha : this.handlerAdapters) { if (logger.isTraceEnabled()) { logger.trace("Testing handler adapter [" + ha + "]"); } // 返回该Handler符合Adapter规则的HandlerAdapter,(检查Handler是否实现了指定的接口)(HandlerAdapter是一个接口具体返回的时springmvc配置文件中配置的适配器) 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. 执行Handler获取模型视图对象ModelAndView
doDispatcher
中执行的mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
由配置文件中具体配置的适配器决定,以 SimpleControllerHandlerAdapter
为例:
@Override public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 调用程序员子集实现的Handler的handleRequest方法 return ((Controller) handler).handleRequest(request, response); }
4. 根据返回的view进行视图渲染,将模型数据填充到request域
DispatcherServlet中的processDispatchResult方法:
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception { boolean errorView = false; // 处理异常视图 if (exception != null) // ... // Did the handler return a view to render? if (mv != null && !mv.wasCleared()) { // 视图渲染与模型数据填充到request域 render(mv, request, response); if (errorView) { WebUtils.clearErrorRequestAttributes(request); } } else { if (logger.isDebugEnabled()) { logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() + "': assuming HandlerAdapter completed request handling"); } } // ... }
render(mv, request, response)
方法:
@Override public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception { if (logger.isTraceEnabled()) { logger.trace("Rendering view with name '" + this.beanName + "' with model " + model + " and static attributes " + this.staticAttributes); } Map<String, Object> mergedModel = createMergedOutputModel(model, request, response); prepareResponse(request, response); // 模型数据填充到request域 renderMergedOutputModel(mergedModel, getRequestToExpose(request), response); }
继续打开renderMergedOutputModel
方法,由于renderMergedOutputModel
是抽象方法,找到实现类InternalResourceView
(以配置文件中配置的视图解析器InternalResourceViewResolver
为例
):
@Override protected void renderMergedOutputModel( Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { // 将模型数据填充到request域中:Expose the model object as request attributes. exposeModelAsRequestAttributes(model, request); // 设置转发的路径等 }
继续打开exposeModelAsRequestAttributes()
方法:
protected void exposeModelAsRequestAttributes(Map<String, Object> model, HttpServletRequest request) throws Exception { for (Map.Entry<String, Object> entry : model.entrySet()) { String modelName = entry.getKey(); Object modelValue = entry.getValue(); if (modelValue != null) { // 将模型数据填充到request请求域! request.setAttribute(modelName, modelValue); if (logger.isDebugEnabled()) { logger.debug("Added model object '" + modelName + "' of type [" + modelValue.getClass().getName() + "] to request in view with name '" + getBeanName() + "'"); } } else { request.removeAttribute(modelName); if (logger.isDebugEnabled()) { logger.debug("Removed model object '" + modelName + "' from request in view with name '" + getBeanName() + "'"); } } } }
Done!
0 0
- Spring MVC Basic Process Flow
- spring mvc learn process
- Expert Spring MVC and Web Flow (Expert)
- 深入解析Spring MVC与Web Flow
- SAP MM Process Flow
- Motherboard Production Process Flow
- SD process flow
- PFD - Process Flow Diagram
- SD Process Flow and tables
- OPNET Basic Process Lesson
- basic python2(conditions & control flow)
- Spring Basic
- Oracle Back to Back Process Flow
- Form Query Process Flow(F11 -> Ctrl+F11)
- Internal Sales Order (ISO) Process Flow
- Form Query Process Flow(F11 -> Ctrl+F11)
- Internal Sales Order (ISO) Process Flow
- Internal Sales Order (ISO) Process Flow
- hdu 3081 Marriage Match II【并查集+二分+最大流Dinic+建图】
- SharedPreferencesCompat的由来与简单解析
- Spring Boot默认的日志格式
- mysql日期格式化大全
- 各widget控件
- Spring MVC Basic Process Flow
- POJ 1061青蛙的约会 扩展欧几里得
- From Keyframes to Key Objects: Video Summarization by Representative Object Proposal Selection
- HDU 3923 Invoker
- 大数据_Storm_Storm集群的搭建
- Linux系统应用管理方法探究
- KafKa基于Zookeeper集群安装
- 生无可恋
- springMVC 事物配置的5种方式