Tomcat 收到一个请求时,透过一系列组件的执行,到达 DispatcherServlet:
DispatcherServlet.java
@Override
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
... ...
doDispatch(request, response);
}
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerExecutionChain mappedHandler = null;
ModelAndView mv = null;
... ...
// 1
mappedHandler = getHandler(processedRequest);
// 2
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 3
if (!mappedHandler.applyPreHandle(processedRequest, response))
return;
// 4
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// 5
mappedHandler.applyPostHandle(processedRequest, response, mv);
// 6
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
1. mappedHandler = getHandler(processedRequest);
第一步,通过 Request 查找符合条件的 HandlerMapper,返回对象 HandlerExecutionChain;这是一个执行链,其中包含有符合本次 Request 的处理器 Handler(Controller)和拦截器 HandlerInterceptor。
HandlerExecutionChain.java
public class HandlerExecutionChain {
private static final Log logger = LogFactory.getLog(HandlerExecutionChain.class);
private final Object handler;
@Nullable
private HandlerInterceptor[] interceptors;
@Nullable
private List<HandlerInterceptor> interceptorList;
private int interceptorIndex = -1;
... ...
}
2. HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
第二步,通过 Handler(Controller)获取 HandlerAdapter,获取过程其实就是判断该 Handler 是否能够被HandlerAdapter 所处理。
DispatcherServlet.java
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
if (this.handlerAdapters != null) {
for (HandlerAdapter ha : this.handlerAdapters) {
... logger ...
// Here
if (ha.supports(handler)) {
return ha;
}
}
}
... throw exception ...
}
HandlerAdapter.java
public interface HandlerAdapter {
boolean supports(Object handler);
@Nullable
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
long getLastModified(HttpServletRequest request, Object handler);
}
HandlerAdapter 是 SpringMVC 中真正调用 Handler(Controller)的组件,就是该接口中的第二个方法,方法中处理调用完 Handler(Controller)后返回结果 ModelAndView,DispatcherServlet 中得到结果后继续往下处理视图渲染的步骤;HandlerAdapter 的子类中有比较熟悉常用的 RequestMappingHandlerAdapter。
不过在 HandlerAdapter 调用 Handler(Controller)之前,SpringMVC 提供了灵活的插件式处理方式,所以先执行前置处理第 3 步。
3. mappedHandler.applyPreHandle(processedRequest, response)
第三步,如果该 Handler(Controller)中有对应的拦截器 HandlerInterceptor,则调用拦截器前置处理方法:
HandlerExecutionChain.java
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
// Here
if (!interceptor.preHandle(request, response, this.handler)) {
triggerAfterCompletion(request, response, null);
return false;
}
this.interceptorIndex = i;
}
}
return true;
}
4. mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
第四步,由具体的 HandlerAdapter 调用方法触发 Handler 对应的处理方法,返回结果 ModelAndView。
5. mappedHandler.applyPostHandle(processedRequest, response, mv);
第五步,如果该 Handler(Controller)中有对应的拦截器 HandlerInterceptor,则调用拦截器后置处理方法 postHandle( )。
6. processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
最后,将 HandlerAdapter 处理后返回的 ModelAndView 结果渲染,调用对应的一些渲染组件,如 LocaleResolver (本地化)、ViewResolver (视图解析器)等。
在这一步的最后还会触发一些收尾工作,调用 HandlerInterceptor 的 afterCompletion(...)。
附:SpringMVC 处理流程图