在SpringMVC的模式下,浏览器的一个请求是如何映射到指定的controller的呢?
初始化映射关系
在web服务器启动时,Spring容器中会保存一个map的数据结构,里边记录这controller和url请求中的对应关系。那么这个map中的数据是如何来的呢?
首先来看AbstractHandlerMethodMapping的initHandlerMethods方法(至于为什么直接找到这个方法,我也是网上搜索的,之前的调用链没去纠结)
protected void initHandlerMethods() {
if (logger.isDebugEnabled()) {
logger.debug("Looking for request mappings in application context: " + getApplicationContext());
}
//获取Spring容器装配的所有bean的名称
String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?
BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :
getApplicationContext().getBeanNamesForType(Object.class));
//遍历
for (String beanName : beanNames) {
//判断该bean是否有@controller或者@RequestMapping注解
if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX) &&
isHandler(getApplicationContext().getType(beanName))){
//如果有上述注解,则需要保存对应关系
detectHandlerMethods(beanName);
}
}
handlerMethodsInitialized(getHandlerMethods());
}
protected void detectHandlerMethods(final Object handler) {
//获取传过来handler的类信息
Class<?> handlerType =
(handler instanceof String ? getApplicationContext().getType((String) handler) : handler.getClass());
// Avoid repeated calls to getMappingForMethod which would rebuild RequestMappingInfo instances
//初始化一个保存映射信息的map
final Map<Method, T> mappings = new IdentityHashMap<Method, T>();
final Class<?> userType = ClassUtils.getUserClass(handlerType);
Set<Method> methods = HandlerMethodSelector.selectMethods(userType, new MethodFilter() {
@Override
public bo