HandlerMapping的初始化发生在核心类:AbstractHandlerMethodMapping中,该类实现了InitializingBean,且RequestMappingHandlerMapping为该类子类,spring启动过程中会通过回调afterPropertiesSet方法完成HandlerMethod的初始化。
初始化的过程实际上是将Controller中的方法注册到MappingRegistry中,MappingRegistry为AbstractHandlerMethodMapping的内部类,用于存放@RequestMapping中定义的URL路径(抽象为RequestMappingInfo)与对应Controller方法(抽象为HandlerMethod)的映射关系。注册过程源码解析如下。
HandlerMethod的初始化:
@Override
public void afterPropertiesSet() {
initHandlerMethods();
}
扫描ApplicationContext中所有的bean,找到handler methods并注册:
protected void initHandlerMethods() {
if (logger.isDebugEnabled()) {
logger.debug("Looking for request mappings in application context: " + getApplicationContext());
}
//获取spring容器中所有的beanNames
String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(obtainApplicationContext(), Object.class) :
obtainApplicationContext().getBeanNamesForType(Object.class));
for (String beanName : beanNames) {
//排除以scopedTarget.开头的bean
if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
Class<?> beanType = null;
try {
//获取beanName对应的类型
beanType = obtainApplicationContext().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);
}
}
//isHandler()检测是否是handler,
//模版方法RequestMappingHandlerMapping.isHandler()
//判断是否是@controller 或者 @RequestMapping
if (beanType != null && isHandler(beanType)) {
//查找HandlerMethods并注册
detectHandlerMethods(beanName);
}
}
}
//改方法方法体为空,RequestMappingHandlerMapping也没有扩展改方法
handlerMethodsInitialized(getHandlerMethods());
}
查找并注册当前Handler中的Mehods:
protected void detectHandlerMethods(final Object handler) {
//获取当前Handler的类型
Class<?> handlerType = (handler instanceof String ?
obtainApplicationContext().getType((String) handler) : handler.getClass());
if (handlerType != null) {
//针对CGLIB生成的子类,找到真正用户定义的类型userType
final Class<?> userType = ClassUtils.getUserClass(handlerType);
//从Class中获取<Method,RequestMappingInfo>
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.isDebugEnabled()) {
logger.debug(methods.size() + " request handler methods found on " + userType + ": " + methods);
}
for (Map.Entry<Method, T> entry : methods.entrySet()) {
//判断Method是否可调用(不是private方法)
Method invocableMethod = AopUtils.selectInvocableMethod(entry.getKey(), userType);
//RequestMappingInfo(方法上的信息)
T mapping = entry.getValue();
//将Handler,Method,RequestMappingInfo注册到MappingRegistry中
registerHandlerMethod(handler, invocableMethod, mapping);
}
}
}