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)方法,主要包含以下步骤:

  1. 调用处理器映射器,根据请求的url查找处理的Handler,返回HandlerChain;
  2. 调用处理器适配器执行Handler,返回ModelAndView;
  3. 请求进行视图(ViewResolver)解析;
  4. 根据返回的View进行视图渲染;
  5. 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
原创粉丝点击