applyDefaultViewName(request, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
}
catch (Exception ex) {
dispatchException = ex;
}
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
}
catch (Error err) {
triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
}
finally {
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
}
else {
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
}
}
}
}
先来看看Spring中一个简单的映射处理器配置:
<bean
>
<property>
<props>
<prop key="/test.html">controller</prop>
</props>
</property>
</bean>
在Spring的加载中,会将类型为SimpleUrlHandlerMapping的实例加载到this.handlerMappings中,根据request提取对应的Handler,也就是提取当前实例的controller,这里的controller是继承自AbstractController类型实例,看看这步是如何封装的,跟进getHandler方法源码:
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
for (HandlerMapping hm : this.handlerMappings) {
if (logger.isTraceEnabled()) {
logger.trace(
"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
}
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {
return handler;
}
}
return null;
}
在系统启动时Spring会将映射类型的bean注册到this.handlerMappings变量中,此方法的目的就是遍历所有的HandlerMapping,并调用其getHandler方法进行封装处理,跟进SimpleUrlHandlerMapping的getHandler方法:
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
// 根据request获取对应的handler
Object handler = getHandlerInternal(request);
if (handler == null) {
// 如果没有则使用默认的handler
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
if (handler instanceof String) {
String handlerName = (String) handler;
handler = getApplicationContext().getBean(handlerName);
}
return getHandlerExecutionChain(handler, request);
}
上面源码应该很清晰,根据request获取对应的Handler,如果没有的话则使用默认的,当查找到的controller为String类型时,就意味着返回的是配置的bean名称,需要根据bean名称查找对应的bean,最后通过getHandlerExecutionChain方法对返回的Handler进行封装,以满足返回类型的匹配。
接着跟进getHandlerInternal方法源码来看看怎样根据request查找对应的Handler: