摘要:概述通過前三章的分析,我們簡要分析了和,但對攔截器部分做詳細的分析,攔截器的加載和初始化是三個相同的部分。
概述
通過前三章的分析,我們簡要分析了SimpleUrlHandlerMapping、BeanNameUrlHandlerMapping和RequestMappingHandlerMapping,但對攔截器部分做詳細的分析,攔截器的加載和初始化是三個HandlerMapping相同的部分。本節補充下這塊內容。
本系列文章是基于Spring5.0.5RELEASE。
類圖類的繼承關系,如下圖:
我們知道Spring MVC將請求發送到Handler(Controller)處理器的功能是通過HandlerMapping組件完成的,HandlerMapping組件除了能找到Handler,還對攔截器進行了處理,具體實現是通過AbstractHandlerMapping抽象類完成的。
源碼分析HandlerMapping
HandlerMapping接口只定義了一個方法getHandler,其作用是返回請求的處理鏈HandlerExecutionChain,該對象封裝了請求的攔截器以及請求處理Handler,方法定義如下:
@Nullable HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
AbstractHandlerMapping
類聲明源碼如下:
public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport implements HandlerMapping, Ordered { // ... ... }
從類的定義可知道,AbstractHandlerMapping抽象類繼承WebApplicationObjectSupport并實現了HandlerMapping和Ordered接口,其中:
繼承WebApplicationObjectSupport類提供了上下文ApplicationContext和ServletContext
實現HandlerMapping接口為我們提供查找handler處理器功能
實現Ordered接口,以提供排序能力,比如系統中使用多個HandlerMapping,可以定義每個HandlerMapping的順序
簡言之,AbstractHandlerMapping類為我們提供上下文環境、初始化攔截器并封裝到HandlerExecutionChain對象中。
該類的入口方法,源代碼如下:
/** * 初始化攔截器 */ @Override protected void initApplicationContext() throws BeansException { // 提供給子類去重寫的,不過Spring并未去實現 extendInterceptors(this.interceptors); // 加載攔截器 detectMappedInterceptors(this.adaptedInterceptors); // 歸并攔截器 initInterceptors(); } /** * 空實現 */ protected void extendInterceptors(List
至此,攔截器初始化完成,接下來我們分析getHandler方法,源碼如下:
/** * 返回請求處理的HandlerExecutionChain */ @Override @Nullable public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { // getHandlerInternal()為抽象方法,具體需子類實現 Object handler = getHandlerInternal(request); if (handler == null) { handler = getDefaultHandler(); } if (handler == null) { return null; } // Bean name or resolved handler? if (handler instanceof String) { String handlerName = (String) handler; handler = obtainApplicationContext().getBean(handlerName); } // 將請求處理器封裝為HandlerExectionChain HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request); // 對跨域的處理 if (CorsUtils.isCorsRequest(request)) { CorsConfiguration globalConfig = this.globalCorsConfigSource.getCorsConfiguration(request); CorsConfiguration handlerConfig = getCorsConfiguration(handler, request); CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig); executionChain = getCorsHandlerExecutionChain(request, executionChain, config); } return executionChain; } /** * 鉤子函數,需子類實現 */ @Nullable protected abstract Object getHandlerInternal(HttpServletRequest request) throws Exception; /** * 構建handler處理器的HandlerExecutionChain,包括攔截器 */ protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) { HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ? (HandlerExecutionChain) handler : new HandlerExecutionChain(handler)); String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); // 迭代添加攔截器 for (HandlerInterceptor interceptor : this.adaptedInterceptors) { // 如果攔截器是MappedInterceptor,判斷是否對該handler進行攔截,是的情況下添加 if (interceptor instanceof MappedInterceptor) { MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor; if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) { chain.addInterceptor(mappedInterceptor.getInterceptor()); } } else { // HandlerInterceptor直接添加,即通過HandingMapping屬性配置的攔截器 chain.addInterceptor(interceptor); } } return chain; }總結
本節我們補充了攔截器的加載初始化過程以及getHandler方法的實現分析,希望對大家有所幫助。
最后創建了qq群方便大家交流,可掃描加入,同時也可加我qq:276420284,共同學習、共同進步,謝謝!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69510.html
摘要:接口接口作用是將請求映射到處理程序,以及預處理和處理后的攔截器列表,映射是基于一些標準的,其中的細節因不同的實現而不相同。該參數是類型,作用是檢查所有的映射解析器或使用或為的,默認為,即從上下文中檢查所有的。 概述 在Spring MVC啟動章節https://segmentfault.com/a/1190000014674239,介紹到了DispatcherServlet的onRef...
摘要:與類圖對比,類繼承自抽象類,其又繼承自抽象類,再往上繼承關系與一致。創建初始化上一章我們分析了的創建初始化過程,的創建初始化過程與一樣,方法的入口在抽象類中的方法。至此,代碼編寫完畢。 概述 本節我們繼續分析HandlerMapping另一個實現類BeanNameUrlHandlerMapping,從類的名字可知,該類會根據請求的url與spring容器中定義的bean的name屬性值...
摘要:概述上一節我們分析了的初始化過程,即創建并注冊,本章我們分析下的請求處理過程,即查找。本系列文章是基于。最后創建了群方便大家交流,可掃描加入,同時也可加我,共同學習共同進步,謝謝 概述 上一節我們分析了RequestMappingHandlerMapping的初始化過程,即創建并注冊HandlerMehtod,本章我們分析下RequestMappingHandlerMapping的請求...
摘要:由于抽象類重寫了父類的方法,所以此時會調用的方法,在該方法中通過調用父類的方法,該方法通過模板方法模式最終調到類的方法。分析該類間接實現了接口,直接實現該接口的是抽象類,映射與請求。 概述 在前一章https://segmentfault.com/a/1190000014901736的基礎上繼續分析,主要完成SimpleUrlHandlerMapping類的原理。 本系列文章是基于Sp...
摘要:默認支持該策略。以上是對的宏觀分析,下面我們進行內部細節分析。整體流程一通過實現接口,完成攔截器相關組件的初始化調用類的方法。總結本文主要分析了的初始化過程,希望對大家有幫助。隨著學習的深入,后面有時間在分析下期中涉及的關鍵,比如等等。 概述 本節我們繼續分析HandlerMapping另一個實現類ReqeustMappingHandlerMapping,該類是我們日常開發中使用最多的...
閱讀 1776·2021-10-27 14:15
閱讀 3835·2021-10-08 10:12
閱讀 1168·2021-09-22 15:55
閱讀 3230·2021-09-22 15:17
閱讀 834·2021-09-02 15:40
閱讀 1748·2019-08-29 18:33
閱讀 1099·2019-08-29 15:22
閱讀 2355·2019-08-29 11:08