這裏貼一個我認爲寫得不錯得SpringMVC源碼分析的博客
SpringMVC源碼分析系列
引用一張它的圖
一、SpringMVC主要發揮作用的是哪些類
HandlerMapping(AbstractHandlerMethodMapping)維護url和HandlerMethod之間的關係
HandlerMethod包含的信息是:類,方法,參數
HandlerAdapter是具體執行HandlerMethod的
DispatcherServlet在接到請求後就根據HandlerMapping找到HandlerMethod
閱讀源碼的時候啓動的時候主要關注的入口在AbstractHandlerMethodMapping,請求的時候主要關注的入口在DispatcherServlet
二、SpringMVC在啓動的時候做了什麼
啓動的時候在SpringIOC執行finishBeanFactoryInitialization(beanFactory)實例化所有不是懶加載的的Bean的時候
實例化requestMappingHandlerMapping完,做初始化的時候,會調用requestMappingHandlerMapping的afterPropertiesSet方法,而該方法會調用父類AbstractHandlerMethodMapping的
源碼如下:
protected void initHandlerMethods() {
if (logger.isDebugEnabled()) {
logger.debug("Looking for request mappings in application context: " + getApplicationContext());
}
//得到SpringMVC中所有Object類的對象(所有bean)
String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :
getApplicationContext().getBeanNamesForType(Object.class));
//便利所有Bean
for (String beanName : beanNames) {
if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
Class<?> beanType = null;
try {
beanType = getApplicationContext().getType(beanName);
}
catch (Throwable ex) {
// An unresolvable bean type, probably from a lazy bean - let's ignore it.
if (logger.isDebugEnabled()) {
logger.debug("Could not resolve target class for bean with name '" + beanName + "'", ex);
}
}
//如果該bean有@Controller或者@RequestMapping修飾
if (beanType != null && isHandler(beanType)) {
//解析出這個controller中的每一個方法和方法對應的url,存到AbstractHandlerMethodMapping類的mappingRegistry中。key是url和httpmethod,value是包、類、方法、入參
detectHandlerMethods(beanName);
}
}
}
handlerMethodsInitialized(getHandlerMethods());
}
做了幾件事:
1.得到SpringIOC中所有的bean
2.遍歷所有的bean,找到有@Controller和@RequestMapping修飾的bean
3.接着第二步,解析這些bean,每一個可以被請求的方法(@RequestMapping)解析出URL和對應的處理方法
4接着第三步,把這些URL和HandlerMethod對應的關係保存到AbstractHandlerMethodMapping類的mappingRegistry中。
第4步中維護了幾個MAP,他們分別是:
mappingLookup key是RequestMappingInfo value是handlerMethod
key和value內容示例
urlLookup key是url value是RequestMappingInfo
nameLookup key是name valus是List<HandlerMethod>
registry key是RequestMappingInfo value是MappingRegistration