前面對springMV處理請求的過程做了整體的描述,以及對它的理解,但對于尋找Handler的細節(jié),還是有必要在仔細研究一下,加深記憶!
總體步驟
遍歷所有的HandlerMapping
在遍歷過程中,通過每個HandlerMapping的getHandler方法尋找Handler對象
在getHandler方法中,調(diào)用geHandlertInternal方法實際的尋找Handler對象,該方法會根據(jù)不同的方式來尋找不同類型的Handler。
問題
首先要遍歷HandlerMapping,那HandlerMapping是怎么來的?先上代碼
這個方法是在著名的DispatcherServlet里面,該方法由initStrategies方法的調(diào)用,而initStrategies又由onRefresh來調(diào)用,onRefresh方法是重寫父類的方法,DispatherServlet的父類FrameworkServlet在初始化WebApplicationContext時,調(diào)用這個鉤子方法,由子類來實現(xiàn),即現(xiàn)在的DispatherServlet。記住這點,后面學習ApplicationContext的時候就有例子可以參考了。
在初始化的開始,對是否加載所有的HandlerMapping做了判斷,如果不加載全部的HandlerMapping,就會加載一個名為“handlerMapping”的Bean作為一個單例的mapping,如果這個Bean也沒有找到,則會加載默認的handlerMapping。
加載所有HandlerMapping的方式,就是利用反射來加載所有實現(xiàn)了HandlerMapping接口的類。
另外,對于WebApplicationContext有些思考:其實WebApplicationContext充當了一個適配器的角色,它一方面集成了Spring的ApplicationContext,也就意味著和Spring做了集成;另外一方面它又包含了ServletContext,這就意味著又集成了Servlet容器的上下文,最后就是我們的Servlet容器和web 應(yīng)用擁有了強大的spring的能力。

默認的HandlerMapping有哪些?
所謂默認的HandlerMapping,我指的時spring自帶的HandlerMapping。上圖:

從上圖看,總共有七個HandlerMapping,現(xiàn)在來歸納一下:
AbstractHandlerMapping是最高層的抽象類,是積累它本身不能算是一種HandlerMapping。
AbstractUrlHandlerMapping是一種HandlerMapping,所謂一種,指的的是通過請求匹配Bean的方式,看類名就知道這是通過url來找匹配的Bean作為Handler;其中SimpleUrlHandlerMapping就是它的實現(xiàn)類。
AbstractDetectingUrlHandlerMapping雖然也是AbstractUrlHandlerMapping的實現(xiàn)類,但它是一種新的尋找HandlerBean的方式,所以我認為它是一種HandlerMapping,其中BeanNameUrlHandlerMapping就是它的實現(xiàn)類,BeanNameUrlHandlerMapping的匹配Bean的方式就是通過將url作為beanName,來加載Bean。
AbstractHandlerMethodMapping是一種新的Mapping方式,mapping過程是先通過url尋找Handler對象,然后再通過url匹配處理請求的方法,并將該方法封裝成HandlerMethod對象,來具體處理請求。
最后的MatchableHandlerMapping,其實并不是一個新的mapping方式,只是增加了一個請求匹配的內(nèi)部功能。
總上來看,springMvc中一共提供了3種尋找Handler的方式,一是通過url匹配Handler對象,二是通過url匹配HandlerMethod對象,三是通過將url作為beanName來匹配Handler對象。