springmvc中配置這個標簽默認注冊三個bean:RequestMappingHandlerMapping,RequestMappingHandlerAdapter,DefaultHandlerExceptionResolver
RequestMappingHandlerMapping
我們看它實現了InitializingBean 接口,所以在getBean()實例化它時會執行afterPropertiesSet()方法,來看該方法干了什么?
方法中實例化了一個BuilderConfiguration對象,並為該對象設置了一些路徑抓取器,路徑方法匹配器等。最后還需要調用父類的方法
父類只是調用了initHandlerMethods()方法,該方法很關鍵是將請求路徑和方法匹配的
// 獲得所有的beanName
// 遍歷所有的beanName並獲得type類型
// 判斷類是否被@Controller或是@RequestMapping注釋了,是執行detectHandlerMethods(beanName)方法
// 首先獲得類型class,根據類的class獲得一個Map,這個map的key是Method,value是RequestMappingInfo,后文詳解#1
// 遍歷map,獲得Method和RequestMappingInfo,注冊他們。后文詳解#2
書接前文#1
selectMethods()方法中,根據類的class獲得所有的方法,遍歷方法執行doWith(Method method)方法
獲得方法和RequestMappingInfo,將他們存到Map中返回,RequestMappingInfo是怎么獲得的呢?我們馬上來看
執行的是detectHandlerMethods()方法中的getMappingForMethod(method, userType)方法,該方法是一個抽象方法。RequestMappingHandlerMapping執行方法
// 創建方法的RequestMappingInfo,后文詳解#1-1
// 創建類的RequestMappingInfo,該步驟和上一步如出一轍
// 將前兩者結合,后文詳解#1-2
書接前文#1-1
// 獲得方法上的@RequestMapping注解的信息,根據注解創建RequestMappingInfo
這里使用了建造者模式創建,我們來看build()方法干了什么?
方法中關鍵的是PatternsRequestCondition對象,該對象的patterns屬性保存了方法注解的路徑值如 /app,創建了RequestMappingInfo返回
書接前文#1-2
方法中分別使用結合方法,然后重新創建一個返回,我們主要來看一下PatternsRequestCondition的方法
使用了AntPathMatcher對象結合類注解路徑和方法注解路徑,如果沒有通配符則簡單拼接如 /person , /list --> /person/list
重新創建一個返回
書接前文#2
AbstractHandlerMethodMapping中使用MappingRegistry屬性對象注冊
// 創建HandlerMethod對象,后文詳解#2-1
// 將映射和對應的方法存起來
// 獲得映射路徑,將映射路徑和映射對象存起來。后文詳解#2-2
// 獲得RequestMappingInfo的name,將name和method存起來
// 將映射對象和映射注冊對象存起來
書接前文#2-1
HandlerMethod中,有beanName,beanFactory,method,methodParameter
書接前文#2-2
獲得RequestMappingInfo中的PatternsRequestCondition中的patterns屬性值
至此RequestMappingHandlerMapping的初始化完成了