1、在SpringMVC的http請求處理過程中,包括了前端控制器(DispatcherServlet)、處理映射器(HandlerMapping)、處理適配器(HandlerAdapter)、處理器((Handler)Controller)、視圖解析器(ViewReslover)、視圖(View)這六大主要對象。他們負責對http請求做處理,具體流程如下圖。
第一步:前端控制器dispatcher接受請求
Client---url--->Dispatcher
第二步:前端控制器去發起handler映射查找請求
Dispatcher---HttpServletRequest---> HandlerMapping
第三步:處理器映射器查找hanlder並返回HandlerExetuionChain
Dispatcher <---HandlerExeutionChain---HandlerMapping
第四步:前端控制器發起請求處理器適配器請求執行
Dispatcher---Handler---> HandlerAdapter
第五步:處理器適配器去調用handler執行
HandlerAdapter---HttpServletRequest> Handler(Controller)
第六步:處理器處理后返回ModelAndView給HandlerAdapter
HandlerAdapter <---ModelAndView---Handler(Controller)
第七步:處理器適配器將ModelAndView返回給前端控制器
Dispatcher <---ModelAndView---HandlerAdapter
第八步:前端控制器請求視圖解析器解析ModelAndView
Dispatcher---ModelAndView---> ViewReslover
第九步:視圖解析器解析視圖后返回視圖View給前端控制器
Dispatcher <---View---ViewReslover
第十步:前端控制器請求視圖要求渲染視圖
Dispatcher--->View--->render
第十一步:前端控制器返回響應
Response <---Dispatcher
源碼探秘
第一步接受請求:
我們可以來看看DispatcherServlet的繼承結構
其實DispatcherServlet能處理請求是因為HttpServlet類的service方法,而HttpServlet又來自Servlet接口定義的規范。
可以看到抽象類HttpServlet實現了接口Servlet的service方法,根據請求類型不同執行了不同的方法(doGet,doPost)
當請進來后,由HttpServlet的子類FrameworkServlet重寫的service方法執行請求,可以看到437行子類調用了父類的service方法,然后在父類執行doGet之類的方法時,由於子類FrameworkServlet重寫了父類方法,交由子類執行,所以進到了我的doGet斷點里面,它調用了處理請求方法。
接下來我們看看ProcessRequest方法的源碼
前面一系列初始化工作我們先不管,看看重要的部分,try里面的doService方法
跟蹤進去看了一下,由於它是抽象方法,所以會由子類實現和執行,也就是我們的DispatchServlet類了
老規矩,先貼上源碼,它是DispatchServlet的doService方法--------------------------------------------------------------------------------------------------------------
所以第一步也就完成了,第一步的任務就是走進這里來。
第二步:前端控制器去發起handler映射查找請求
Dispatcher---HttpServletRequest---> HandlerMapping
上面的源碼中主要工作就是給request實例設置一系列參數,要注意的就是doDispatch方法,這里面就是mvc的核心了,前面第一張交互圖里面的流程都是在這里實現的。
可以看到,通過HttpRequestServlet作為參數請求handlerMapping
第三步:處理器映射器查找hanlder並返回HandlerExetuionChain
Dispatcher <---HandlerExeutionChain---HandlerMapping
可以看到上圖中返回了mappedHandler變量,就是HandlerExtuceChain類型
可以看到,已經找到並返回了我們的HomeController處理器(Hanlder)
第四步:前端控制器發起請求處理器適配器請求執行
Dispatcher---Handler---> HandlerAdapter
從508行可以看到,適配器傳入handler對象和reaquest等信息,執行handler()方法
第五步:處理器適配器去調用handler執行
HandlerAdapter---HttpServletRequest> Handler(Controller)
從這里可以看到,調用的handlerInternal是個抽象方法,會調用子類的實現方法,子類由RequestMappingHandlerAdapter實現,這個類也是我們經常在xml里面配置的類
通過invokeHandlerMethod方法執行進到controller里面
方法執行后返回我們的index
第六步:處理器處理后返回ModelAndView給HandlerAdapter
HandlerAdapter <---ModelAndView---Handler(Controller)
通過調用invokeHandlerMethod方法返回ModelAndView
第七步:處理器適配器將ModelAndView返回給前端控制器
Dispatcher <---ModelAndView---HandlerAdapter
第八步:前端控制器請求視圖解析器解析ModelAndView
Dispatcher---ModelAndView---> ViewReslover
第九步:視圖解析器解析視圖后返回視圖View給前端控制器
Dispatcher <---View---ViewReslover
可以看到,返回的視圖,url指向index.jsp頁面
第十步:前端控制器請求視圖要求渲染視圖
Dispatcher--->View--->render
如果View對象不為空,將會調用render方法渲染
如果返回的是json對象,屬於接口的,是不會走這里的
此時會找對應的視圖解析器去渲染
里面其實也沒干啥,就做了個跳轉,到jsp頁面去綁定數據
第十一步:前端控制器返回響應
Response <---Dispatcher
到這里也就基本上完了。
處理請求完成后做了個重置工作,然后發布一個事件,你可以選擇監聽這個事件,做相應處理。
再看看response里面
這個就是我們頁面上的內容了。