【SpringMVC】SpringMVC Source Code - Running Process

Description

面试题:来给我说一下Spring MVC的执行过程?

After reading the passage above, I feel more confused about how SpringMVC runs, what HandlerMapping is, what differences between HandlerMapping and HandlerAdapter, etc. Talk is cheap, so let’s dive into the source code to make it clear.

In order to understand the running process of SpringMVC through source code reading, we are gonna build a SpringMVC project using IDEA firstly.

Environment & Tools

IntelliJ IDEA 2018.3 (Ultimate Edition), JRE: 1.8, maven 3.6, SpringBoot 2.0.5.RELEASE,

Guide

build a SpringMVC project

download the project: git clone https://github.com/spring-guides/gs-serving-web-content.git

open in IDEA: complete is the whole project, while initial is only the framework

2019.03.20 - 01

run the project

2019.03.20 - 02

visit http://localhost:8080/greeting in browser, succeed

2019.03.20 - 03

source code reading in debug mode

rerun the project in debug mode

download the source code and start from DispatcherServlet

2019.03.20 - 04

if failed downloading, try mvn dependency:resolve -Dclassifier=sources in terminal

2019.03.20 - 05

DispatcherServlet

from the comment, we can easily get to know that doDispatch() process the actual dispatching to the handler

so after setting a breakpoint in doDispatch() and visit http://localhost:8080/greeting in the browser, we get to this

2019.03.20 - 06

then we skip over to the method getHandler() and skip into it

2019.03.20 - 07

HandlerMapping

it iterates the list of HandlerMapping and get a handler in type of HandlerExecutionChain

2019.03.20 - 08

2019.03.20 - 09

then we come to getHandlerAdapter()

2019.03.20 - 10

HandlerAdapter

again, it iterates the list of HandlerAdapter and get a HandlerAdapter

2019.03.20 - 11

run some preHandle with interceptors.preHandle()

2019.03.20 - 12

invoke the handler through HandlerAdapter, and get ModelAndView

2019.03.20 - 13

run some postHandle with interceptors.postHandle()

2019.03.20 - 14

then we come to processDispatchResult()

2019.03.20 - 15

2019.03.20 - 16

2019.03.20 - 17

ViewResolver

it iterates the list of ViewResolver and get a view

2019.03.20 - 18

Summary

In conclusion, when we post a request, it will be intercepted and handled by DispatcherServlet in doDispatch() method. Then it iterates List<HandlerMapping> handlerMappings to get HandlerExecutionChain handler, which is where the controller belongs to. Then it iterates List<HandlerAdapter> handlerAdapters to get HandlerAdapter ha, which is used to execute the controller we define. Then run HandlerInterceptor[] interceptors.preHandle(), execute HandlerExecutionChain handler through HandlerAdapter ha and get ModelAndView mv, run HandlerInterceptor[] interceptors.postHandle(). Finally, it iterates List<ViewResolver> viewResolvers to render ModelAndView mv.

Reference

官网-Serving Web Content with Spring MVC

IDEA建立Spring MVC Hello World 详细入门教程

官网-Web on Servlet Stack

idea 无法下载依赖包的source,使用maven下载source

Q&A

Q: What is these: multipart resolver, HandlerMapping, HandlerExecutionChain, HandlerAdapter, ModelAndView?

Q: Why do we use HandlerAdapter ha to execute HandlerExecutionChain handler?

A: I guess it relates to the Adapter Design Pattern, and for scalability.