接上一篇:Spring MVC源碼解析三
在上一篇對于DispatcherServlet中的doDispatch方法解讀時,可以看到是通過以下的代碼實現(xiàn)根據(jù)request獲取handler的
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest);
我們可以看下getHandler是怎么處理的:
/**
* Return the HandlerExecutionChain for this request.
* <p>Tries all handler mappings in order.
* @param request current HTTP request
* @return the HandlerExecutionChain, or {@code null} if no handler could be found
*/
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;
}
可以看到通過循環(huán)調(diào)用this.handlerMappings中的HandlerMapping實例的getHandler方法返回HandlerExecutionChain實例,這里必然有幾個問題需要解答:
為什么返回的是一個HandlerExecutionChain的實例,而不是一個“Handler”類盏浇? HandlerMapping的getHandler方法如何實現(xiàn)的掏熬?
首先看HandlerExecutionChain這個類:
/**
* Handler execution chain, consisting of handler object and any handler interceptors.
* Returned by HandlerMapping's {@link HandlerMapping#getHandler} method.
*
* @author Juergen Hoeller
* @since 20.06.2003
* @see HandlerInterceptor
*/
public class HandlerExecutionChain {
......
private final Object handler;
private HandlerInterceptor[] interceptors;
private List<HandlerInterceptor> interceptorList;
private int interceptorIndex = -1;
......
}
通過類的注釋可以看到,HandlerExecutionChain是由handler對象和handler攔截器對象(注意這里是復(fù)數(shù))組成的:
HandlerExecutionChain中包含handler對象镀梭,這個好理解虹茶,getHandler原本的目的就是通過url獲取到對應(yīng)的handler逝薪,那么handler攔截器(handler interceptors是干嘛的)
HandlerExecutionChain中的field:interceptors和interceptorList便是handler攔截器的容器,攔截器對應(yīng)的類是HandlerInterceptor蝴罪,我們看下它做了什么事情
這里有個需要注意的地方董济,HandlerExecutionChain中為什么定義了interceptors和interceptorList2個屬性,他們的區(qū)別是什么要门?不細(xì)講了虏肾,有興趣的可以自己去看HandlerExecutionChain的源碼
HandlerInterceptor的源碼:
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
default void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
}
default void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
}
}
HandlerInterceptor是一個接口廓啊,定義了3個回調(diào)接口:
- preHandle:在handler執(zhí)行前調(diào)用
- postHandle:在handler執(zhí)行,View調(diào)用render接口前后調(diào)用
- afterCompletion:在handler執(zhí)行完成封豪,切View調(diào)用render結(jié)束后調(diào)用
這里其實攔截器的基本用途已經(jīng)很清晰了谴轮,類似于proxy,在handler調(diào)用前后進行一些操作吹埠,如果用戶想在controller的方法執(zhí)行前實現(xiàn)一些通用的日志操作第步,就可以去實現(xiàn)HandlerInterceptor接口(具體代碼如何寫需要做什么配置,這里不細(xì)化了缘琅,搜下就清楚了)
關(guān)于getHandler的返回值類型HandlerExecutionChain的解讀到此結(jié)束了粘都,下一章繼續(xù)講HandlerMapping和它的getHandler接口的邏輯處理