spring mvc源码解读三 ---RequestMappingHandlerMapping初始化

RequestMappingHandlerMapping也是存在路径与类的关系,它是存放以下的方式配置Controller的对应关系

@Controller
@RequestMapping("/cong")
public class TestController {
	@RequestMapping("/test")
	@ResponseBody
	public String test(){
		return "123";
	}
}

首先不多说,先看调用栈

从调用栈来看,基本和 BeanNameUrlHandlerMapping初始化类似,区别在于BeanNameUrlHandlerMapping是通过后置处理器初始化对应关系,而RequestMappingHandlerMapping通过实现InitializingBean来实现,熟悉spring初始化的生命周期的都知道,spring在创建完bean之后都会执行InitializingBean 的afterPropertiesSet()方法

 从调用栈来看,会调用这个方法AbstractHandlerMethodMapping的processCandidateBean方法

	protected void processCandidateBean(String beanName) {
		Class<?> beanType = null;
		try {
			beanType = obtainApplicationContext().getType(beanName);
		}
		catch (Throwable ex) {
			// An unresolvable bean type, probably from a lazy bean - let's ignore it.
			if (logger.isTraceEnabled()) {
				logger.trace("Could not resolve type for bean '" + beanName + "'", ex);
			}
		}
		if (beanType != null && isHandler(beanType)) {
			detectHandlerMethods(beanName);
		}
	}

其中isHandler会判断是否有@Controller注解

最后调用 AbstractHandlerMethodMapping的detectHandlerMethods方法

	protected void detectHandlerMethods(Object handler) {
		Class<?> handlerType = (handler instanceof String ?
				obtainApplicationContext().getType((String) handler) : handler.getClass());

		if (handlerType != null) {
			Class<?> userType = ClassUtils.getUserClass(handlerType);
			Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
					(MethodIntrospector.MetadataLookup<T>) method -> {
						try {
							return getMappingForMethod(method, userType);
						}
						catch (Throwable ex) {
							throw new IllegalStateException("Invalid mapping on handler class [" +
									userType.getName() + "]: " + method, ex);
						}
					});
			if (logger.isTraceEnabled()) {
				logger.trace(formatMappings(userType, methods));
			}
			methods.forEach((method, mapping) -> {
				Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);
				registerHandlerMethod(handler, invocableMethod, mapping);
			});
		}
	}

从代码看,就是通过反射把各个方法映射到map中,其中在RequestMappingHandlerMapping的mappingLookup熟悉就是存放这个的,至此已经把映射存放好,再等访问的时候就可以通过url来匹配对应的bean和方法,再看一下调试信息

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值