国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

SpringMVC之源碼分析--HandlerMapping(六)

BDEEFE / 3215人閱讀

摘要:概述上一節我們分析了的初始化過程,即創建并注冊,本章我們分析下的請求處理過程,即查找。本系列文章是基于。最后創建了群方便大家交流,可掃描加入,同時也可加我,共同學習共同進步,謝謝

概述

上一節我們分析了RequestMappingHandlerMapping的初始化過程,即創建并注冊HandlerMehtod,本章我們分析下RequestMappingHandlerMapping的請求處理過程,即查找HandlerMethod。

本系列文章是基于Spring5.0.5RELEASE。

總體流程

因本節重點分析RequestMappingHandlerMapping處理請求方式,所以我們從請求到達前端控制器(DispatcherServlet)的doDispatch方法開始,之前的請求處理可參考https://segmentfault.com/a/1190000014712270

流程描述:

用戶請求到達前端控制器DispatcherServlet.doDispatch方法

在doDispatch方法中調用本類的getHandler方法

getHandler方法調用HandlerMapping的getHandler方法

HandlerMapping.getHandler方法由抽象類AbstractHandlerMapping實現,故最終調用AbstracthandlerMapping.getHandler方法

在AbstractHandlerMapping的getHandler方法中調用鉤子函數getHandlerInternal方法,該方法由子類AbstractHandlerMethodMapping實現

最終由AbstracthandlerMethodMapping.getHandlerInternal返回處理器方法即HandlerMethod

HandlerMethod代表查找到的處理請求Controller中的方法

返回給AbstractHandlerMapping,最終由其將處理器方法和攔截器組裝成HandlerExectionChain對象返回

源碼分析

DispatcherServlet

處理用戶請求的方法到達doDispatch方法,源碼如下:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    // ... ...
    
    //查找請求的處理器
    mappedHandler = getHandler(processedRequest);
    if (mappedHandler == null) {
        // 未找到處理器時跑異常
        noHandlerFound(processedRequest, response);
        return;
    }

    // ... ...
}

@Nullable
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
    if (this.handlerMappings != null) {
        // 迭代Spring支持的HandlerMapping,即我們配置或默認的HandlerMapping
        for (HandlerMapping hm : this.handlerMappings) {
            if (logger.isTraceEnabled()) {
                logger.trace(
                        "Testing handler map [" + hm + "] in DispatcherServlet with name "" + getServletName() + """);
            }
            // 查找請求的處理器HandlerExecutionChain,包括請求需要的攔截器
            HandlerExecutionChain handler = hm.getHandler(request);
            if (handler != null) {
                return handler;
            }
        }
    }
    return null;
}

AbstractHandlerMethodMapping

提供查出處理器模板方法,具體實現由子類實現getHandlerInternal方法實現,代碼如下:

@Override
@Nullable
public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
    // 子類需實現getHandlerInternal方法,本例中由AbstractHandlerMethodMapping實現
    Object handler = getHandlerInternal(request);
    if (handler == null) {
        handler = getDefaultHandler();
    }
    if (handler == null) {
        return null;
    }
    // 如果handler是bean名字,則根據名字從上下文獲取到處理類
    if (handler instanceof String) {
        String handlerName = (String) handler;
        handler = obtainApplicationContext().getBean(handlerName);
    }
    // 返回請求處理的HandlerExecutionChain對象
    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;
}

AbstractHandlerMethodMapping

本類主要提供創建并注冊HandlerMethod以及查找HandlerMethod功能,處理用戶請求時,源碼如下:

/**
 * 實現父類(AbstractHandlerMapping)的鉤子函數
 */
@Override
protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
    // 使用工具類UrlPathHelper,解析用戶請求url
    String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
    if (logger.isDebugEnabled()) {
        logger.debug("Looking up handler method for path " + lookupPath);
    }
    this.mappingRegistry.acquireReadLock();
    try {
        // 查找HandlerMethod核心方法
        HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
        if (logger.isDebugEnabled()) {
            if (handlerMethod != null) {
                logger.debug("Returning handler method [" + handlerMethod + "]");
            }
            else {
                logger.debug("Did not find handler method for [" + lookupPath + "]");
            }
        }
        return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
    }
    finally {
        this.mappingRegistry.releaseReadLock();
    }
}

/**
 * 查找當前請求的處理器方法
 */
@Nullable
protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
    // 定義匹配到的matches集合,其內存放匹配到的Match對象
    List matches = new ArrayList<>();
    // 根據請求url查找出RequestMappingInfo對象
    List directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
    if (directPathMatches != null) {
        // 將查找到的RequestMappingInfo和處理器方法封裝成Match對象存入到matches數組
        addMatchingMappings(directPathMatches, matches, request);
    }
    // 為查詢到RequestMappingInfo時
    if (matches.isEmpty()) {
        // this.mappingRegistry.getMappings().keySet()--返回已注冊所有的RequestMappingInfo
        // 查找到將RequestMappingInfo和處理器方法封裝后存入matches數組
        addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);
    }
    // 有匹配對象
    if (!matches.isEmpty()) {
        // 排序處理
        Comparator comparator = new MatchComparator(getMappingComparator(request));
        matches.sort(comparator);
        if (logger.isTraceEnabled()) {
            logger.trace("Found " + matches.size() + " matching mapping(s) for [" + lookupPath + "] : " + matches);
        }
        // 取出Match,其封裝了RequestMappingInfo和處理器方法
        Match bestMatch = matches.get(0);
        if (matches.size() > 1) {
            if (CorsUtils.isPreFlightRequest(request)) {
                return PREFLIGHT_AMBIGUOUS_MATCH;
            }
            Match secondBestMatch = matches.get(1);
            if (comparator.compare(bestMatch, secondBestMatch) == 0) {
                Method m1 = bestMatch.handlerMethod.getMethod();
                Method m2 = secondBestMatch.handlerMethod.getMethod();
                throw new IllegalStateException("Ambiguous handler methods mapped for HTTP path "" +
                        request.getRequestURL() + "": {" + m1 + ", " + m2 + "}");
            }
        }
        // 主要是往Request的Attribute區放了些東西,具體啥用我也不懂
        handleMatch(bestMatch.mapping, lookupPath, request);
        // 返回處理器方法HandlerMethod
        return bestMatch.handlerMethod;
    }
    else {
        // 未找到處理
        return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);
    }
}
總結

本節對RequestMappingHandlerMapping處理用戶請求時的整體流程及核心源碼進行了分析,如有問題或建議大家可掃描下方二維碼進群反饋,我會知無不言言無不盡,希望對大家有所幫助。

最后創建了qq群方便大家交流,可掃描加入,同時也可加我qq:276420284,共同學習、共同進步,謝謝!

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69516.html

相關文章

  • SpringMVC源碼分析--HandlerMapping(一)

    摘要:接口接口作用是將請求映射到處理程序,以及預處理和處理后的攔截器列表,映射是基于一些標準的,其中的細節因不同的實現而不相同。該參數是類型,作用是檢查所有的映射解析器或使用或為的,默認為,即從上下文中檢查所有的。 概述 在Spring MVC啟動章節https://segmentfault.com/a/1190000014674239,介紹到了DispatcherServlet的onRef...

    ralap 評論0 收藏0
  • SpringMVC源碼分析--HandlerMapping(五)

    摘要:概述通過前三章的分析,我們簡要分析了和,但對攔截器部分做詳細的分析,攔截器的加載和初始化是三個相同的部分。 概述 通過前三章的分析,我們簡要分析了SimpleUrlHandlerMapping、BeanNameUrlHandlerMapping和RequestMappingHandlerMapping,但對攔截器部分做詳細的分析,攔截器的加載和初始化是三個HandlerMapping相...

    nanchen2251 評論0 收藏0
  • SpringMVC源碼分析--HandlerMapping(三)

    摘要:與類圖對比,類繼承自抽象類,其又繼承自抽象類,再往上繼承關系與一致。創建初始化上一章我們分析了的創建初始化過程,的創建初始化過程與一樣,方法的入口在抽象類中的方法。至此,代碼編寫完畢。 概述 本節我們繼續分析HandlerMapping另一個實現類BeanNameUrlHandlerMapping,從類的名字可知,該類會根據請求的url與spring容器中定義的bean的name屬性值...

    fsmStudy 評論0 收藏0
  • SpringMVC源碼分析--HandlerMapping(二)

    摘要:由于抽象類重寫了父類的方法,所以此時會調用的方法,在該方法中通過調用父類的方法,該方法通過模板方法模式最終調到類的方法。分析該類間接實現了接口,直接實現該接口的是抽象類,映射與請求。 概述 在前一章https://segmentfault.com/a/1190000014901736的基礎上繼續分析,主要完成SimpleUrlHandlerMapping類的原理。 本系列文章是基于Sp...

    Imfan 評論0 收藏0
  • SpringMVC源碼分析--HandlerMapping(四)

    摘要:默認支持該策略。以上是對的宏觀分析,下面我們進行內部細節分析。整體流程一通過實現接口,完成攔截器相關組件的初始化調用類的方法。總結本文主要分析了的初始化過程,希望對大家有幫助。隨著學習的深入,后面有時間在分析下期中涉及的關鍵,比如等等。 概述 本節我們繼續分析HandlerMapping另一個實現類ReqeustMappingHandlerMapping,該類是我們日常開發中使用最多的...

    imccl 評論0 收藏0

發表評論

0條評論

BDEEFE

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<