原文鏈接:
https://juejin.im/post/5e6b0ee3e51d4526f65cdb50.
0x0 先看名詞
DispactherServlet
:SpringMVC 的心臟,所有的請求從這裏進入,也從這裏出去HandlerAdapter
:請求處理器HandlerMapping
:請求和處理對象間的映射關係,可以理解爲 地址 /api 對應 @RequestMapping("/api")doDispatch
:SpringMVC
處理請求的方法ModelAndView
:視圖響應對象,例如我們Controller返回一個字符串,都會被包裝成它ViewResolvers
:視圖解析器,解析響應結果爲瀏覽器能識別的網頁或者文件ContentNegotiatingViewResolver
:SpringMVC
提供的視圖內容協商器,根據響應視圖類型來判斷使用哪個解析器來解析,是使SpringMVC
支持多視圖解析器的重要組件,官方說明:https://spring.io/blog/2013/06/03/content-negotiation-using-views
0x1 一個請求過來
請求進入 DispactherServlet
會被分配給 doDispatch
,所以直接斷點 doDispatch
即可
0x01 請求處理器
doDispatch
會匹配相應的 HandlerMapping
(可以理解爲你在 Controller
中寫的方法),然後執行並拿到返回結果(也就是 ModelAndView
)
0x02 視圖解析器
DispactherServlet
會將ModelAndView
交給 ViewResolvers
(也就是常說的視圖解析器) 解析處理。
ViewResolvers
中 ContentNegotiatingViewResolver
(詳見 0x0 解釋)它去問所有的視圖解析器:這個 ModelAndView
你們能解析的了嗎?,如下圖:
類:ContentNegotiatingViewResolver
如何確定誰纔是天選之子解析器?MediaType
!按照順序,第一個符合 MediaType
的解析器將被使用。
PS:比如你響應的是 text/html 文件,但是 text/html
解析器有兩個,你想優先使用其中一個的話,你就得爲該解析器設置 Order
(詳見 0x0 中官方說明)
得到 ModelView
以後,視圖解析器的任務就算完成了
0x03 合併模板
下一步跳轉到 視圖處理
進入 render
方法後,會執行 Prepares the view given the specified model, merging it with static ,通俗講就是將我們 Request
域或者 Session
域 中的值(比如說請求參數回顯)和視圖解析出來的 ModelAndView 進行合併,這也是爲什麼我們再模板中可以輕鬆獲得各種作用域值的原因,繼續往下看
組裝 ModelAndView
執行視圖合併
獲取模板文件和語言信息
將 ModelAndView
中的屬性全部傳遞給 FreeMarker
最後一步生成 Html
並響應到瀏覽器
0x2 靜態資源處理
SpringMVC
在視圖處理器如果找不到合適的處理器的情況下,就會視該請求爲靜態資源請求並使用靜態資源解析器解析該請求。
默認的靜態資源目錄如下,這也是爲什麼你將靜態資源放在 resource
目錄的時候不需要任何配置便可訪問的原因
如果本文對你有幫助,歡迎關注並點贊~ 任何問題請評論區或者公衆號留言。
關注本人公衆號,收穫雙倍快樂
技術交流羣,廣告勿+