現在使用SpringMVC這個框架已經有一年多了,到現在還是只知道怎么寫Dao,Service,Controller層,對於其實現原理還是一無所知,
所以還是想進一步提升自己對於框架的原理的理解。
本文旨在分析一個http請求如何映射到對應的Controller的,讓讀者明白框架到底做了哪些事情。
源碼的版本是4.3.2.RELEASE。
因為RequestMappingHandleMapping是處理請求與HandlerMethod映射關系的一個核心類,
首先看下它的繼承關系圖:
首先看一下AbstractHandlerMethodMapping的initHandlerMethods方法中。
它首先找到Spring容器中初始化所有的Bean,然后isHandler方法是抽象方法,有其子類RequestMappingHandlerMapping去實現,
可看到RequestMappingHandlerMapping的isHandler函數是查找是否有含有@Controller或RequestMapping注解的類。
接下來是detectHandlerMethods函數代碼;
可以看出其中有個methods變量的Map類型,Key是Method,Value是RequestMappingInfo(如上圖:RequestMappingInfoHandlerMapping繼承AbstractHandlerMethodMapping實現,傳入泛型
為RequestMappingInfo), 這里getMappingForMethod方法也是抽象方法,由RequestMappingHandlerMapping實現如下圖所示,然后調用registerHandlerMethod方法.這個函數里是用
MappingRegistry(它是AbstractHandlerMethodMapping內部類),注冊 HandlerMethod.
在這個函數中創建了方法的RequestMappingInfo,和類的RequestMappingInfo,並且合並到一起。
這個函數創建了RequestMappingInfo這個對象,找到含有@RqquestMapping的類和函數,並創建RequestMappingInfo對象。
可以看到RequestMappingInfo對象包含路徑、方法、參數、請求頭、名字、自定義類型等。builder方法后,創建RequestMappingInfo
對象。(這里用的是構造者模式)
可以看到,RequestMappingInfo類中包含PatternsRequestCondition,RequestMethodsRequestCondition、ParasRequestCondition、
HeadersRequestCondition等類,主要看一下url的patternsCondition的類的url匹配的類的獲取匹配路徑。
可以看到首先匹配的是.,然后是帶有通配符的.*。接着尋找匹配的路徑。
這個注冊handlerMethod方法,是屬於AbstractHandlerMethodMapping的一個內部類MappingRegistry,用來
專門維持所有的映射方法,並提供方法去查找方法去提供當前url映射的方法。這段代碼主要是創建handlerMethod對象,
其中維護幾個Map(鍵值對),用來存儲映射的信息, 還有一個MappingRegistration專門保存注冊信息的。
結束:
本文只是對一個 http請求到正確匹配映射對應Controller層的方法的做了一些單簡要的分析,雖然自己的水平有限,又很多地方
還是沒有弄的很明白,文中難免有錯誤,也希望您指出來,歡迎有一起探討學習SpringMVC的框架的同學。也包括探討其他關於框架技術的。