一、HandlerMapping
HandlerMapping作用是根據request找到相應的處理器Handler和Interceptors,並將Handler和Interceptors封裝成HandlerExecutionChain 對象返回。HandlerMapping接口裏面只有一個方法。
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
HandlerMapping繼承結構如下圖:
可以看到HandlerMapping家族的成員分兩支,一支繼承AbstractUrlHandlerMapping,另一支繼承AbstractHandlerMethodMapping,而這兩支都繼承自抽象類AbstractHandlerMapping。
1.1 AbstractHandlerMapping
AbstractHandlerMapping是HandlerMapping的抽象實現,所有HandlerMapping都繼承自AbstractHandlerMapping。AbstractHandlerMapping採用的是模板方法的設計模式,具體的算法由子類去完成。
來看一下主要的方法 getHandler()
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
//根據request獲取handler,具體由子類實現
Object handler = getHandlerInternal(request);
//找不到handler就獲取默認的Handler
if (handler == null) {
handler = getDefaultHandler();
}
if (handler == null) {
return null;
}
// handler是bean name情況下,在Spring容器上下文根據該name檢索
if (handler instanceof String) {
String handlerName = (String) handler;
handler = obtainApplicationContext().getBean(handlerName);
}
// 這裏將檢索到的Handler和Interceptors封裝到HandlerExecutionChain 對象中
HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
//省略
....
return executionChain;
}
可以看出getHandlerInternal方法是抽象方法,由子類實現。接下來看一下getHandlerExecutionChain方法。
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
//將handler設置到HandlerExecutionChain 中
HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));
// 裝配Interceptor
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
if (interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
}
else {
chain.addInterceptor(interceptor);
}
}
return chain;
}
這個方法也非常簡單,首先使用handler創建出HandlerExcutionChain類型的變量,然後將adaptedInterceptors和符合要求的mappedInterceptors添加進去,最後將其返回。AbstracthandlerMapping中保存了所用配置的Interceptor,在獲取到Handler後會自己根據從Request提取的lookupPath將相應的Interceptors裝配上去,當然子類也可以通過getHandlerInternal方法設置自己的Interceptor。
1.2AbstractUrlHandlerMapping
未完待續。。。