【十五】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

 

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