一次請求 SpringMVC 到底做了什麼?


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 即可

一次請求 SpringMVC 到底做了什麼?


0x01 請求處理器

doDispatch 會匹配相應的 HandlerMapping (可以理解為你在 Controller 中寫的方法),然後執行並拿到返回結果(也就是 ModelAndView)

一次請求 SpringMVC 到底做了什麼?

0x02 視圖解析器

DispactherServlet 會將ModelAndView交給 ViewResolvers(也就是常說的視圖解析器) 解析處理。

ViewResolvers 中 ContentNegotiatingViewResolver(詳見 0x0 解釋)它去問所有的視圖解析器:這個 ModelAndView 你們能解析的了嗎?,如下圖:

類:ContentNegotiatingViewResolver

一次請求 SpringMVC 到底做了什麼?

如何確定誰才是天選之子解析器?MediaType!按照順序,第一個符合 MediaType 的解析器將被使用。

PS:比如你響應的是 text/html 文件,但是 text/html 解析器有兩個,你想優先使用其中一個的話,你就得為該解析器設置 Order (詳見 0x0 中官方說明)

一次請求 SpringMVC 到底做了什麼?

一次請求 SpringMVC 到底做了什麼?


得到 ModelView 以後,視圖解析器的任務就算完成了


0x03 合併模板

下一步跳轉到 視圖處理

一次請求 SpringMVC 到底做了什麼?

進入 render 方法後,會執行 Prepares the view given the specified model, merging it with static ,通俗講就是將我們 Request 域或者 Session域 中的值(比如說請求參數回顯)和視圖解析出來的 ModelAndView 進行合併,這也是為什麼我們再模板中可以輕鬆獲得各種作用域值的原因,繼續往下看

一次請求 SpringMVC 到底做了什麼?

組裝 ModelAndView

一次請求 SpringMVC 到底做了什麼?

執行視圖合併

一次請求 SpringMVC 到底做了什麼?

一次請求 SpringMVC 到底做了什麼?

獲取模板文件和語言信息

一次請求 SpringMVC 到底做了什麼?

將 ModelAndView 中的屬性全部傳遞給 FreeMarker

一次請求 SpringMVC 到底做了什麼?

最後一步生成 Html 並響應到瀏覽器

一次請求 SpringMVC 到底做了什麼?

0x2 靜態資源處理

SpringMVC 在視圖處理器如果找不到合適的處理器的情況下,就會視該請求為靜態資源請求並使用靜態資源解析器解析該請求。

默認的靜態資源目錄如下,這也是為什麼你將靜態資源放在 resource 目錄的時候不需要任何配置便可訪問的原因

一次請求 SpringMVC 到底做了什麼?


分享到:


相關文章: