【十五】Spring源码分析之MVC------启动时AbstractHandlerMethodMapping维护url-handlerMethod的关系

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章