这里贴一个我认为写得不错得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