天天看點

Spring mvc之源碼 handlerMapping和handlerAdapter分析

 Spring mvc之源碼 handlerMapping和handlerAdapter分析

本篇并不是具體分析Spring mvc,是以好多細節都是一筆帶過,主要是帶大家梳理一下整個Spring mvc的執行流程,以及如何根據URL查找處理器Controller的實作

(适合那些剛閱讀源碼不知道如何下手的人)

http://www.guojinbao.com/borrow/borrowDetail/GETadLPjnf0[d].do

如何根據URL位址----》找到正确處理器Controller的相應方法Method

注:概念 IOC容器:負責bean的建立和維護bean與bean關系的一個大的集合

①dispatcherServlet 在Spring MVC為所有請求入口,标準的servlet。

标準的servlet執行流程為

1.init()  首次加載servlet 整個servlet生命周期隻執行一次

2.service()  依據url-pattern(<url-pattern>/</url-pattern> 攔截所有請求,不包括靜态資源檔案) 攔截模式,比對請求模式,比對成功調用service方法

3.destroy()  servlet容器(如:tomcat停止)結束調用

Spring mvc之源碼 handlerMapping和handlerAdapter分析

執行流程如下

第一步 執行 HttpServletBean-->init()方法

Spring mvc之源碼 handlerMapping和handlerAdapter分析

init()方法我們隻需要關注initServletBean()方法 此方法為抽象方法由FrameworkServlet實作

Spring mvc之源碼 handlerMapping和handlerAdapter分析

有興趣的可以具體看一下源碼,整個init()方法 為spring mvc的IOC容器初始化

注:Spring 的IOC容器初始化由contextLoaderListener完成

Spring mvc之源碼 handlerMapping和handlerAdapter分析

Spring IOC容器建議配置:資料庫連接配接,事務,與第三方架構內建等等

如:ApplicationContext.xml  (小提示:處理器Controller的掃描 可以交給springMVC IOC容器完成,目的分層明确,便于IOC容器查找 )  

Spring mvc之源碼 handlerMapping和handlerAdapter分析

Spring mvc IOC 容器 配置:

Spring mvc之源碼 handlerMapping和handlerAdapter分析

第二部 攔截請求

① FrameworkServlet -->service()

分發請求

② FrameworkServlet--->processRequest(request, response);

③ DispatcherServlet--->doService(HttpServletRequest request, HttpServletResponse response)

如何根據URL找到處理器執行正确的方法就在此方法中

④ DispatcherServlet--->doDispatch(HttpServletRequest request, HttpServletResponse response)

 第①部分

Spring mvc之源碼 handlerMapping和handlerAdapter分析

這裡為啥不是調用super.service(request,response)?

Spring mvc之源碼 handlerMapping和handlerAdapter分析

最直接的理由:如果直接調用service方法 根據method類型進行分發請求就直接跳出架構啦(你懂的嘿嘿)

②③2步有興趣的可以看一下源碼

第④部分

DispatcherServlet--->doDispatch(HttpServletRequest request, HttpServletResponse response)

Spring mvc之源碼 handlerMapping和handlerAdapter分析
Spring mvc之源碼 handlerMapping和handlerAdapter分析

整個過程如下:

>>1. 擷取url對應的處理器controller以及相應方法

>>2. 擷取執行處理器中方法的對象

>>3. 具體執行

Spring mvc是如何通過URL查找到對應的處理器controller以及對應的方法尼?需要知道以下3個核心接口handlerMapping,handlerAdapter,RequestCondition我們不具體分析相應接口的實作以及具體邏輯,過程相當複雜,1到2句話說

不清楚,這裡給大家留一個直覺的考量。

由于Spring mvc源碼龐大,建議看源碼的時候,隻看重點部分或者說自己感興趣部分。我們大家常用是在類和方法加上注解@RequestMapping來辨別通路路徑,我們以此模闆給大家量化分析url查詢處理器controller以及相應方法的過程

handlerMapping:負責查找URL對應的處理器Controller

RequestMappingInfo:根據注解@RequestMapping生成方法比對政策

handlerAdapter:負責綁定參數,執行請求,處理傳回值

handlerMapping 接口就一個方法傳回HandlerExecutionChain

Spring mvc之源碼 handlerMapping和handlerAdapter分析

HandlerExecutionChain

Spring mvc之源碼 handlerMapping和handlerAdapter分析

 DispatcherServlet--->doDispatch()

第一步 擷取HandlerExecutionChain

Spring mvc之源碼 handlerMapping和handlerAdapter分析
Spring mvc之源碼 handlerMapping和handlerAdapter分析

在DispatcherServlte的servlet初始化中(調用init()方法)中調用onRefresh()完成handlerMappings的初始化

Spring mvc之源碼 handlerMapping和handlerAdapter分析

第二步 擷取handlerAdapter 找到和handlerMapping比對的handlerAdapter

Spring mvc之源碼 handlerMapping和handlerAdapter分析

初始化過程同第一步

DispatcherServlte會根據handlerMapping與已經注冊好了的HandlerAdapter一一比對,看哪一種HandlerAdapter是支援該handlerMapping類型的,

如果找到了其中一種HandlerAdapter是支援傳過來的handlerMapping類型,那麼該HandlerAdapter會調用自己的handle方法,handle方法運用Java的反射機制執行controller的具體方法來獲得ModelAndView

以handlerMapping的實作RequestMappingHandlerMapping為例

Spring mvc之源碼 handlerMapping和handlerAdapter分析

由于實作了InitializingBean,當RequestMappingHandlerMapping完成bean的初始化後,會調用afterPropertiesSet()-->initHandlerMethods();完成以下操作

①生成直接URL-->RequestMappingInfo,映射操作

Spring mvc之源碼 handlerMapping和handlerAdapter分析

②生成 RequestMappingInfo--->handlerMethod映射操作

Spring mvc之源碼 handlerMapping和handlerAdapter分析

③将所有的RequestMappingInfo注冊到容器中

注:

RequestMappingInfo實作了RequestCondition接口 存儲着根據注解@RequestMapping生成方法比對政策

舉個例子

Spring mvc之源碼 handlerMapping和handlerAdapter分析
Spring mvc之源碼 handlerMapping和handlerAdapter分析

PatternsRequestCondition的初始化相當于

PatternsRequestCondition(“/user/applicationShow/{id}”)當請求URL符合此規則是就比對成功

簡單滴說,RequestMappingInfo是将注解@RequestMapping的資訊提取出來

生成此方法的比對條件

Spring mvc之源碼 handlerMapping和handlerAdapter分析

閱讀RequestMappingHandlerMapping源碼流程如下(主要是為了梳理出重點部分)

Spring mvc之源碼 handlerMapping和handlerAdapter分析
Spring mvc之源碼 handlerMapping和handlerAdapter分析
Spring mvc之源碼 handlerMapping和handlerAdapter分析
Spring mvc之源碼 handlerMapping和handlerAdapter分析

綜上所述我們來猜測一下spring mvc 中根據URL找到處理器Controller中相應方法的流程

①:擷取Request的URL

②:從UrlLookup這個map中找到相應的requestMappingInfo

③:如果沒找到則周遊所有requestMappingInfo的資訊直到找到比對的requestMappingInfo

④:根據requestMappingInfo到mappingLookup中找到handlerMethod

handlerMethod接口如下:

Spring mvc之源碼 handlerMapping和handlerAdapter分析

到這裡大家差不多就明白了吧,有了處理器執行個體,方法,參數調用反射執行方法分分鐘的事情

當然spring mvc真正執行比這個複雜的多啦,但是執行的時候是逃不出這個套路的。

具體的URL找到處理器Controller中相應方法的流程請大家看一下DispatcherServlet--》getHandler()方法

注:

最後說一下RequestMappingHandlerMapping并不是預設的查找處理器方法的政策,他是通過  <mvc:annotation-driven />配置完成容器注冊的

轉載于:https://www.cnblogs.com/huxuhong/p/7245690.html