关于spring-mvc:Spring-MVC-前端控制器-DispatcherServlet处理流程

6次阅读

共计 3574 个字符,预计需要花费 9 分钟才能阅读完成。

Spring MVC 申请解决流程

用户发动申请,到 DispatcherServlet;
而后到 HandlerMapping 返回处理器链(蕴含拦截器和具体解决的 Handler);
调用处理器链的适配器 HandlerAdapter 来解决;
执行具体的办法,比方 @RequestMapper 润饰的逻辑解决办法;
返回后果的视图解析器;
最初进行视图解析和渲染返回后果给用户;

DispatcherServlet
DispatcherServlet 是前置控制器,配置在 web.xml 文件中的。拦挡匹配的申请,Servlet 拦挡匹配规定要本人定义,把拦挡下来的申请,根据相应的规定散发到指标 Controller 来解决,是配置 spring MVC 的第一步。
DispatcherServlet 是前端控制器设计模式的实现,提供 Spring Web MVC 的集中拜访点,而且负责职责的分派,而且与 Spring IoC 容器无缝集成,从而能够取得 Spring 的所有益处。
源码剖析
org.springframework.web.servlet.DispatcherServlet#doDispatch 办法是次要解决申请的源码如下:
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {

try {

    try {
        // 文件上传相干
        processedRequest = checkMultipart(request);
        multipartRequestParsed = (processedRequest != request);

        // DispatcherServlet 收到申请调用处理器映射器 HandlerMapping。// 处理器映射器依据申请 url 找到具体的处理器,生成处理器执行链 HandlerExecutionChain(包含处理器对象和处理器拦截器)一并返回给 DispatcherServlet。mappedHandler = getHandler(processedRequest);
        if (mappedHandler == null) {noHandlerFound(processedRequest, response);
            return;
        }

        4.DispatcherServlet 依据处理器 Handler 获取处理器适配器 HandlerAdapter,
        HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

        // Process last-modified header, if supported by the handler.  HTTP 缓存相干
        String method = request.getMethod();
        boolean isGet = HttpMethod.GET.matches(method);
        if (isGet || HttpMethod.HEAD.matches(method)) {long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
            if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {return;}
        }
        // 前置拦截器
        if (!mappedHandler.applyPreHandle(processedRequest, response)) {
            // 返回 false 就不进行后续解决了
            return;
        }

        // 执行 HandlerAdapter 解决一系列的操作,如:参数封装,数据格式转换,数据验证等操作
        // 执行处理器 Handler(Controller,也叫页面控制器)。// Handler 执行实现返回 ModelAndView
        // HandlerAdapter 将 Handler 执行后果 ModelAndView 返回到 DispatcherServlet
        mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

        if (asyncManager.isConcurrentHandlingStarted()) {return;}
        // 如果没有视图,给你设置默认视图  json 疏忽
        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);
    }
    // DispatcherServlet 将 ModelAndView 传给 ViewReslover 视图解析器
    // ViewReslover 解析后返回具体 View
    // DispatcherServlet 对 View 进行渲染视图(行将模型数据 model 填充至视图中)。// DispatcherServlet 响应用户。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);
        }
    }
}

}
复制代码
在 doDispatch 方中曾经涵盖了 DispatcherServlet 的主要职责:
1、文件上传解析,如果申请类型是 multipart 将通过 MultipartResolver 进行文件上传解析;
2、通过 HandlerMapping,将申请映射到处理器(返回一个 HandlerExecutionChain,它包含一个处理器、多个 HandlerInterceptor 拦截器);
3、通过 HandlerAdapter 反对多种类型的处理器 (HandlerExecutionChain 中的处理器);
4、通过 ViewResolver 解析逻辑视图名到具体视图实现;
5、本地化解析;
6、渲染具体的视图等;
7、如果执行过程中遇到异样将交给 HandlerExceptionResolver 来解析。
DispatcherServlet 初始化的上下文加载的 Bean 是只对 SpringMVC 无效的 Bean,
如 Controller、HandlerMapping、HandlerAdapter 等等,该初始化上下文只加载 Web 相干组件。
DispatcherServlet 初始化次要做了如下两件事件:
1、初始化 SpringMVC 应用的 Web 上下文,并且可能指定父容器为(ContextLoaderListener 加载了根上下文);
2、初始化 DispatcherServlet 应用的策略,如 HandlerMapping、HandlerAdapter 等。

正文完
 0