springMVC启动2

本文详细解析了DispatcherServlet在初始化过程中如何通过刷新IoC容器来初始化RequestMappingHandlerMapping,进而实现请求映射的功能。重点介绍了DispatcherServlet在解析过程中如何通过循环生成并实例化(non-lazy-init)单例,最终找到RequestMappingHandlerMapping,并将其与当前的IoC容器关联起来,以便后续的请求映射处理。

在DispacthServlet类中的initHandlerMappings(context)前,RequestMappingHandlerMapping已经被初始化了;这个过程是怎么进行的呢;其实这个过程是在解析DispatchServlet的过程中,刷新IoC容器时初始化的;

刷新IoC容器在这个调用中触发,实例化单例


// Instantiate all remaining (non-lazy-init) singletons.				finishBeanFactoryInitialization(beanFactory);
List<String> beanNames = new ArrayList<String(this.beanDefinitionNames);
for (String beanName : beanNames) {
//循环生成(non-lazy-init)单例
}

List里的第一个就是RequestMappingHandlerMapping;

后面就是getBean操作;由于RequestMappingHandlerMapping间接的实现ApplicationContextAware

if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}

这里是把当前IoC容器给RequestMappingHanlderMapping让其可以去容器里查找映射;

经过一系列调用,然后是AbstractHandlerMethodMapping,initHandlerMethods方法进行方法扫描

/**
 * Scan beans in the ApplicationContext, detect and register handler methods.
 * @see #isHandler(Class)
 * @see #getMappingForMethod(Method, Class)
 * @see #handlerMethodsInitialized(Map)
 */
protected void initHandlerMethods() {
	if (logger.isDebugEnabled()) {
		logger.debug("Looking for request mappings in application context: " + getApplicationContext());
	}

	String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?
			BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :
			getApplicationContext().getBeanNamesForType(Object.class));
	//循环找出映射
	for (String beanName : beanNames) {
		if (isHandler(getApplicationContext().getType(beanName))){
			detectHandlerMethods(beanName);
		}
	}
	handlerMethodsInitialized(getHandlerMethods());
}

扫描类;并查找映射信息;其中一个重要的类是RequestMappingHandlerMapping。中一个查找方法;

/**
 * Uses method and type-level @{@link RequestMapping} annotations to create
 * the RequestMappingInfo.
 * @return the created RequestMappingInfo, or {@code null} if the method
 * does not have a {@code @RequestMapping} annotation.
 * @see #getCustomMethodCondition(Method)
 * @see #getCustomTypeCondition(Class)
 */
@Override
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
	RequestMappingInfo info = null;
	//查看方法名上是否有@RequestMapping
	RequestMapping methodAnnotation = AnnotationUtils.findAnnotation(method, RequestMapping.class);
	if (methodAnnotation != null) {
	//获取@RequestMapping上的信息
		RequestCondition<?> methodCondition = getCustomMethodCondition(method);
		info = createRequestMappingInfo(methodAnnotation, methodCondition);
		//获取类名上@RequestMapping的信息
		RequestMapping typeAnnotation = AnnotationUtils.findAnnotation(handlerType, RequestMapping.class);
		if (typeAnnotation != null) {
			RequestCondition<?> typeCondition = getCustomTypeCondition(handlerType);
			info = createRequestMappingInfo(typeAnnotation, typeCondition).combine(info);
		}
	}
	return info;
}




转载于:https://my.oschina.net/u/782865/blog/268120

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值