Spring原始碼解讀之Spring MVC HandlerMapping元件(二)
一、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
未完待續。。。