中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Springboot中HandlerMethodArgumentResolver的作用是什么

發布時間:2021-07-08 16:38:15 來源:億速云 閱讀:513 作者:Leah 欄目:大數據

Springboot中HandlerMethodArgumentResolver的作用是什么,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

RequestMappingHandlerAdapter,

      Springboot中HandlerMethodArgumentResolver的作用是什么

                                                               圖1

    HandlerMethodArgumentResolver是個接口,只有倆個方法,supportsParameter返回true標示支持解析,之后調用resolveArgument將結果作為參數傳入,如下List-1所示。

    List-1

public interface HandlerMethodArgumentResolver {
    boolean supportsParameter(MethodParameter var1);

    @Nullable
    Object resolveArgument(MethodParameter var1, @Nullable ModelAndViewContainer var2, NativeWebRequest var3, @Nullable WebDataBinderFactory var4) throws Exception;
}

    RequestMappingHandlerAdapter中有個屬性argumentResolvers,是HandlerMethodArgumentResolverComposite,由類名稱可以看出使用了組合模式。RequestMappingHandlerAdapter的getDefaultArgumentResolvers,這些是默認的參數處理器。

    List-2

private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
    List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>();

    // Annotation-based argument resolution
    resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
    resolvers.add(new RequestParamMapMethodArgumentResolver());
    resolvers.add(new PathVariableMethodArgumentResolver());
    resolvers.add(new PathVariableMapMethodArgumentResolver());
    resolvers.add(new MatrixVariableMethodArgumentResolver());
    resolvers.add(new MatrixVariableMapMethodArgumentResolver());
    resolvers.add(new ServletModelAttributeMethodProcessor(false));
    resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
    resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));
    resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
    resolvers.add(new RequestHeaderMapMethodArgumentResolver());
    resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
    resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
    resolvers.add(new SessionAttributeMethodArgumentResolver());
    resolvers.add(new RequestAttributeMethodArgumentResolver());

    // Type-based argument resolution
    resolvers.add(new ServletRequestMethodArgumentResolver());
    resolvers.add(new ServletResponseMethodArgumentResolver());
    resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
    resolvers.add(new RedirectAttributesMethodArgumentResolver());
    resolvers.add(new ModelMethodProcessor());
    resolvers.add(new MapMethodProcessor());
    resolvers.add(new ErrorsMethodArgumentResolver());
    resolvers.add(new SessionStatusMethodArgumentResolver());
    resolvers.add(new UriComponentsBuilderMethodArgumentResolver());

    // Custom arguments
    if (getCustomArgumentResolvers() != null) {
        resolvers.addAll(getCustomArgumentResolvers());
    }

    // Catch-all
    resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
    resolvers.add(new ServletModelAttributeMethodProcessor(true));

    return resolvers;
}

    如下圖2所示:

 Springboot中HandlerMethodArgumentResolver的作用是什么

                                                              圖2

    DispatcherServlet的doDispatch方法中,間接調用ServletInvocableHandlerMethod的invokeAndHandle方法,之后會逐個調用HandlerMethodArgumentResolver。所以我們自定義的HandlerMethodArgumentResolver在圖2中的步驟9和步驟10處處理。如下List-3所示,遍歷所有的參數,對每個參數調用HandlerMethodArgumentResolverComposite的support和resolve方法,HandlerMethodArgumentResolverComposite再委托給各個HandlerMethodArgumentResolver處理。

    List-3

private Object[] getMethodArgumentValues(NativeWebRequest request, ModelAndViewContainer mavContainer,
        Object... providedArgs) throws Exception {

    MethodParameter[] parameters = getMethodParameters();
    Object[] args = new Object[parameters.length];
    for (int i = 0; i < parameters.length; i++) {
        MethodParameter parameter = parameters[i];
        parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
        args[i] = resolveProvidedArgument(parameter, providedArgs);
        if (args[i] != null) {
            continue;
        }
        if (this.argumentResolvers.supportsParameter(parameter)) {
            try {
                args[i] = this.argumentResolvers.resolveArgument(
                        parameter, mavContainer, request, this.dataBinderFactory);
                continue;
            }
            catch (Exception ex) {
                if (logger.isDebugEnabled()) {
                    logger.debug(getArgumentResolutionErrorMessage("Failed to resolve", i), ex);
                }
                throw ex;
            }
        }
        if (args[i] == null) {
            throw new IllegalStateException("Could not resolve method parameter at index " +
                    parameter.getParameterIndex() + " in " + parameter.getMethod().toGenericString() +
                    ": " + getArgumentResolutionErrorMessage("No suitable resolver for", i));
        }
    }
    return args;
}

    值得注意的是圖2中的步驟12,HandlerMethodReturnValueHandler可以改變controller返還的值。萬一步驟7拋出異常,那么HandlerMethodReturnValueHandler的步驟就不會執行,所以HandlerMethodReturnValueHandler處理不了業務代碼拋出異常的情況。

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

红河县| 蕲春县| 岱山县| 石城县| 固安县| 神木县| 涡阳县| 屏东县| 柘荣县| 临洮县| 莲花县| 洛南县| 高淳县| 光泽县| 曲靖市| 华阴市| 磴口县| 太湖县| 江门市| 监利县| 明光市| 鄂尔多斯市| 东乌珠穆沁旗| 郴州市| 修文县| 德阳市| 夏邑县| 彰武县| 行唐县| 阳山县| 遂川县| 南宫市| 安乡县| 定州市| 齐河县| 轮台县| 潜山县| 沅江市| 神木县| 聂拉木县| 阜宁县|