千家信息网

Springboot中HandlerMethodArgumentResolver的作用是什么

发表于:2025-02-05 作者:千家信息网编辑
千家信息网最后更新 2025年02月05日,Springboot中HandlerMethodArgumentResolver的作用是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,
千家信息网最后更新 2025年02月05日Springboot中HandlerMethodArgumentResolver的作用是什么

Springboot中HandlerMethodArgumentResolver的作用是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

RequestMappingHandlerAdapter,

图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 getDefaultArgumentResolvers() {    List resolvers = new ArrayList();    // 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所示:

图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处理不了业务代码抛出异常的情况。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注行业资讯频道,感谢您对的支持。

0