天天看點

SpringMVC架構源碼解析

這篇blog是學完itheima視訊後進一步學習的内容,是以也是緊接着上一篇blog:

https://blog.csdn.net/qq_43175022/article/details/108933556

源碼分析

雷豐陽大神講解https://www.bilibili.com/video/BV1d4411g7tv?p=156

元件解析 的前四步及九大元件
  1. p156 流程分析
SpringMVC架構源碼解析
  1. p157 -160 doDispatch()方法源碼分析SpringMVC加載過程,對應上文元件解析前7個步驟的内容
  • 157 源碼分析,找到有用方法加注解
  • 158 文字概述上述過程:
SpringMVC架構源碼解析

​ 解析getHandler()方法,引出:getHandler()方法如何根據目前請求找到對應類來處理,即如何傳回目标處理類的執行鍊(同元件解析的第③步)

​ 解決:通過調用HandlerMapping(處理器映射器)儲存每一個處理器對應處理的請求映射資訊

  • 159 解析getHandlerAdapter()方法,解析如何找到擴充卡Adapter,對應④⑤步

    三種傳回值類型的擷取方法:

    HTTPRequestHandlerAdapter()、

    SimpleControllerHandlerAdapter()、

    AnnotationMethodHandlerAdapter()注解擴充卡,重點

  • 160 後續Debug走完元件解析的後續兩步
  1. p161 SpringMVC九大元件:
SpringMVC架構源碼解析

SpringMVC架構源碼解析
SpringMVC架構源碼解析

(沒有翻譯的那個不重要),九大元件作用及共同點:

SpringMVC架構源碼解析
  1. p162 九大元件初始化細節:
SpringMVC架構源碼解析

細節:

SpringMVC架構源碼解析

例如HandlerMapping元件:

SpringMVC架構源碼解析

總結:

SpringMVC架構源碼解析
元件解析中的關鍵點Handler處理 P163-167
  1. p163 聚焦元件解析中⑤⑥步中Handler的目标方法執行:
SpringMVC架構源碼解析
SpringMVC架構源碼解析
SpringMVC架構源碼解析

引出真正執行的方法:

SpringMVC架構源碼解析
  1. p164 invokeHandlerMethod()方法解析,真正執行目标方法的兩個注解(34點)的解析:
  • 首先查找34點中的是否有@SessionAttributes存儲Session,沒有直接執行下一步:
    SpringMVC架構源碼解析
  • 進入@ModelAttribute注解解析細節:
    SpringMVC架構源碼解析
  • 進入resolveHandlerArguments()方法,獲得agrs[]:
    SpringMVC架構源碼解析
    • 該方法使用一個雙層for()循環确定:
    SpringMVC架構源碼解析
    SpringMVC架構源碼解析
    • 然後進行分支判斷找到的注解個數(由于上述注解沖突隻能标一個,出現多個就抛出異常):
    SpringMVC架構源碼解析
    • 分析沒有找到注解的分支:
    SpringMVC架構源碼解析
    • 進入resolveCommonArgument()方法解析普通參數(原生API):

      确定目前參數是否為Servlet原生API,解析成功就将方法傳回的Object賦予上文聲明的args[]

    • 不為普通參數時:
      SpringMVC架構源碼解析
      本例中為map參數,是以傳入隐含模型
  • 獲得args[] (該args隻獲得ModelAttribute注解這一個參數)後,尋找ModelAttribute注解屬性Value的值,賦予attrName
    SpringMVC架構源碼解析
  • 反射Method類型的attributeMethodToInvoke(由for循環疊代周遊獲得的attributeMethod解析而來),使其可通路
  • 運作ModelAttribute提前運作的方法(詳情可見34點)賦予一個Object類型
    SpringMVC架構源碼解析
  • 判斷上述attrName是否為空
    • 不為空上述方法已經指派
    • 為空執行下列語句:
      SpringMVC架構源碼解析
      賦予ModelAttribute方法的傳回值類型首字母小寫(由attributeMethodToInvoke獲得)
  • 判斷隐含模型是否包含attrName,沒有就執行:
    SpringMVC架構源碼解析
    作用:
    SpringMVC架構源碼解析
  • 再次調用resolveHandlerArguments()方法,獲得agrs[]:

    不同的是第一個形參換成了 invokeHandlerMethod()方法的第一個形參handleMethod解析獲得的handlerMethodToInvoke

  • return語句:

    真真正正的執行方法:handlerMethodToInvoke.invoke

總結:ModelAttribute标注的方法提前運作并且把執行後的傳回值放在隐含模型中

  1. p165 166 上文有提及,40點隻是擷取了34點的兩個提前注解的參數資訊,是以需要再次調用resolveHandlerArguments()方法,擷取其他參數的值
  • 165 @RequestParam的普通類型、普通類型、map類型的三個參數獲得流程:
    SpringMVC架構源碼解析
  • 166 POJO類型(自定義類型)參數:
    • 有注解:
      SpringMVC架構源碼解析
    • 沒注解:
      SpringMVC架構源碼解析
    總結:
    SpringMVC架構源碼解析
    步驟:
    • 該方法的内循環的一個分支語句,确定上述值:
      SpringMVC架構源碼解析
    • 進入resolveModelAttribute()方法擷取WebDataBinder執行個體對象:
      SpringMVC架構源碼解析
    • 标紅部分講解,确定POJO的值:
      SpringMVC架構源碼解析
  1. 上述166 167Handler處理獲得參數過程總結(排除兩個提前注解過程):
    SpringMVC架構源碼解析
    SpringMVC架構源碼解析
元件解析的視圖解析部分(最後三步)源碼分析
  1. p172 視圖解析流程:
SpringMVC架構源碼解析

結合代碼重點摘要:

SpringMVC架構源碼解析
SpringMVC架構源碼解析

上述圖檔流程解析:

完成了上文Handler處理獲得ModelAndView對象後,繼續向下執行調用了上述第2點processDispatchResult()方法,該方法方法體中調用了第3點的render()方法渲染頁面,該方法中聲明View(頁面)對象,View調用前端控制器定義的resolveNameView()方法,獲得一個View對象,提出下面第5點問題:

  • 元件解析中的⑧⑨步的視圖解析器調用源碼流程解析:
    SpringMVC架構源碼解析
    • 在前端控制器的resolveNameView()方法中,疊代周遊九大元件之一的ViewResolver對象
      SpringMVC架構源碼解析
      過程中還檢視目前viewResolver對象的獲得方法和預設值
    • 疊代出的目前頁面的視圖解析器調用本身接口自帶的内部resolveNameView()方法,獲得一個View對象:
      SpringMVC架構源碼解析
      進入該resolveViewName()方法(在一個抽象類中):
      • 首先檢視緩存,有就直接擷取
      • 為空時調用createView()方法建立View對象:
        SpringMVC架構源碼解析
        View對象:
        SpringMVC架構源碼解析
        進入createView()方法:
        • 三個不同類型的分支結構判斷建立獲得其中一種View對象:
          SpringMVC架構源碼解析
        • 調用父類執行建立,父類再調用loadView()方法一頓解析,期間又會傳回createView()方法所在類進行解析(略)
      • 獲得一個View對象

        本案例中獲得了一個InternalResourceView對象

        還有一個常用的View對象:RedirectView對象

      • 存入緩存
    • 上述流程總結:
      SpringMVC架構源碼解析
  • 元件解析中的⑩步的視圖解析器調用源碼流程解析:

    上述得到View對象後傳回第三點的render()方法(前端控制器定義的)

    • view對象調用接口自帶的内部render()方法(抽象類中)(上文接口圖示可見該方法):
      SpringMVC架構源碼解析
    • 進入renderMergedOutputModel()方法:

      其中的關鍵方法exposeModelAsRequestAttribute():

      SpringMVC架構源碼解析
    • 進入exposeModelAsRequestAttribute()方法:
      SpringMVC架構源碼解析
    • 回到renderMergedOutputModel()方法:

      取得映射位址并獲得轉發器:

      SpringMVC架構源碼解析
      轉發器轉發:
      SpringMVC架構源碼解析
    如果獲得的View對象是RedirectView對象,就是獲得重定向器,重定向到映射位址。
  • 總結:
    SpringMVC架構源碼解析
攔截器和異常處理源碼 P211 212和P221 226 4P

略。