HandlerMapping分析
HandlerMapping用于尋找處理對應請求的Handler
0x01 流程了解
第一點:了解HandlerMapping接口
HandlerMapping是個接口,主要需要實作方法
getHandler(HttpServletRequest)
,雖然是傳回對應
Handler
,實際上是傳回類
HandlerExecutionChain
第二點:了解HandlerExecutionChain
該類組合了Handler和Interceptor,提供了Interceptor的前後置調用方法。以及Handler相關的設定擷取方法
0x02 設計思路
HandlerMapping設計思路主體為模闆方法模式,
AbstractHandlerMapping
作為HandlerMapping的抽象類,主要有兩點:
第一點:定義了如何擷取Handler的方法架構,子類隻需要實作具體算法即可。即重寫方法
getHandlerInternal
即可
第二點:定義了如何初始化Interceptor,通過繼承類
WebApplicationObjectSupport
,該類實作了
ApplicationContextAware
接口,在
setApplicationContext
方法中調用了
initApplicationContext
方法,該方法被重載提供了無參方法,類似
GenericServlet
中的
init
方法。
AbstractUrlHandlerMapping
繼承了
AbstractHandlerMapping
,重寫了
getHandlerInternal
方法。該類是
AbstractHandlerMapping
的一個分支,通過Map将url和對應handler進行關聯。提供了注冊方法交由子類實作。
SimpleUrlHandlerMapping
繼承該類,重寫了
AbstractHandlerMapping
的
initApplicationContext
方法,除了調用一遍父類方法,還進行了url注冊
AbstractDetectingUrlHandlerMapping
繼承該類,也重寫了
AbstractHandlerMapping
的
initApplicationContext
方法,在其中注冊handler,但是handler的選擇通過抽象方法
determineUrlsForHandler
交由子類實作
AbstractHandlerMethodMapping
不同于
AbstractUrlHandlerMapping
,該類的handler是方法而不是類。如
@RequestMapping
注解的方法。
實作
InitializingBean
,在
afterPropertiesSet
中調用
initHandlerMethods
進行注冊handler,類似url,但是它的對應關系是url和method。
在
initHandlerMethods
中需要子類實作抽象方法
isHandler
和
getMappingForMethod
。前者用于判斷該方法能否作為handler,後者用于擷取該handler
總結
通過抽象類完成主體流程并提供抽象方法,子類隻需完成抽象方法即可。