1.1 前言

上一章节介绍了DispatcherServlet的初始化过程,这一章节介绍核心分发器DispatcherServlet是怎样处理请求的

2.1 DispatcherServlet 处理请求过程

  • 既然DispatcherServlet本身是Servlet,我们就要专注于它的service、doGet、doPost等相关方法,在FrameworkServlet里可以看到service、doGet、doPost这些方法的重载实现,可以看到都是流转到processRequest(request, response);这个方法中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    /**
    * Override the parent class implementation in order to intercept PATCH requests.
    */
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

    HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());
    if (HttpMethod.PATCH == httpMethod || httpMethod == null) {
    processRequest(request, response);
    }
    else {
    super.service(request, response);
    }
    }

    /**
    * Delegate GET requests to processRequest/doService.
    * <p>Will also be invoked by HttpServlet's default implementation of {@code doHead},
    * with a {@code NoBodyResponse} that just captures the content length.
    * @see #doService
    * @see #doHead
    */
    @Override
    protected final void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

    processRequest(request, response);
    }

    /**
    * Delegate POST requests to {@link #processRequest}.
    * @see #doService
    */
    @Override
    protected final void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

    processRequest(request, response);
    }

    /**
    * Delegate PUT requests to {@link #processRequest}.
    * @see #doService
    */
    @Override
    protected final void doPut(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

    processRequest(request, response);
    }

    /**
    * Delegate DELETE requests to {@link #processRequest}.
    * @see #doService
    */
    @Override
    protected final void doDelete(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

    processRequest(request, response);
    }
  • 根据service方法,我们一步步找到一个方法链service –> processRequest –> doService –> doDispatch,我们最终将目光定位在doDispatch,因为从它的方法体就可以看出它是整个SpringMVC的核心方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    /**
    * Process the actual dispatching to the handler.
    * <p>The handler will be obtained by applying the servlet's HandlerMappings in order.
    * The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters
    * to find the first that supports the handler class.
    * <p>All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers
    * themselves to decide which methods are acceptable.
    * @param request current HTTP request
    * @param response current HTTP response
    * @throws Exception in case of any kind of processing failure
    */
    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    HttpServletRequest processedRequest = request;
    HandlerExecutionChain mappedHandler = null;
    boolean multipartRequestParsed = false;
    // 获取当前请求的WebAsyncManager,如果没找到则创建并与请求关联
    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

    try {
    ModelAndView mv = null;
    Exception dispatchException = null;

    try {
    // 检查是否有 Multipart,有则将请求转换为 Multipart 请求
    processedRequest = checkMultipart(request);
    multipartRequestParsed = (processedRequest != request);

    // Determine handler for the current request.
    // 遍历所有的 HandlerMapping 找到与请求对应的 Handler,并将其与一堆拦截器封装到 HandlerExecution 对象中
    mappedHandler = getHandler(processedRequest);
    if (mappedHandler == null || mappedHandler.getHandler() == null) {
    noHandlerFound(processedRequest, response);
    return;
    }

    // Determine handler adapter for the current request.
    // 遍历所有的 HandlerAdapter,找到可以处理该 Handler 的 HandlerAdapter
    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

    // Process last-modified header, if supported by the handler.
    // 处理 last-modified 请求头
    String method = request.getMethod();
    boolean isGet = "GET".equals(method);
    if (isGet || "HEAD".equals(method)) {
    long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
    if (logger.isDebugEnabled()) {
    logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
    }
    if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
    return;
    }
    }

    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
    return;
    }

    // Actually invoke the handler.
    // 执行实际的处理程序
    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

    if (asyncManager.isConcurrentHandlingStarted()) {
    return;
    }

    applyDefaultViewName(processedRequest, mv);
    // 遍历拦截器,执行它们的 postHandle() 方法
    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);
    }
    // 处理执行结果,是一个 ModelAndView 或 Exception,然后进行渲染
    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
    // 遍历拦截器,执行它们的 afterCompletion() 方法
    if (mappedHandler != null) {
    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
    }
    }
    else {
    // Clean up any resources used by a multipart request.
    if (multipartRequestParsed) {
    cleanupMultipart(processedRequest);
    }
    }
    }
    }
  • 说它是核心一点也不为过,从上述代码的中文注释可以看出,它包含了解析请求,执行相关拦截器,执行handle方法,这行代码是真正执行我们controller的方法mv = ha.handle(processedRequest, response, mappedHandler.getHandler());,那SpringMvc是怎样找到我们的方法的呢,下面的章节将介绍

3.1 总结

  • Spring Mvc 的处理方式是先在顶层设计好整体结构,然后将具体的处理交给不同的组件具体去实现
  • DispatcherServlet中的doDispatch方法完成了具体的请求处理,下面是主要流程
    • 遍历所有的 HandlerMapping 找到与请求对应的 Handler,并将其与一堆拦截器封装到 HandlerExecutionChain 对象中
    • 遍历所有的 HandlerAdapter,找到可以处理该 HandlerHandlerAdapter
    • 执行相应拦截器InterceptorpreHandle方法
    • HandlerAdapter 执行Hander,由Hander 执行实际的处理程序,执行Controller里的方法
    • 调用processDispatchResult处理结果
    • 执行相应拦截器InterceptorpostHandle方法
  • 本章只是介绍下Spring MVC的主要流程,下面的章节将详细介绍这些流程,下面是流程图

4.1 参考

官方文档: https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html

http://www.cnblogs.com/fangjian0423/p/springMVC-dispatcherServlet.html

https://blog.csdn.net/lang_programmer/article/details/71598042