您好,登錄后才能下訂單哦!
Springboot中HandlerMethodArgumentResolver的作用是什么,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。
RequestMappingHandlerAdapter,
圖1
HandlerMethodArgumentResolver是個(gè)接口,只有倆個(gè)方法,supportsParameter返回true標(biāo)示支持解析,之后調(diào)用resolveArgument將結(jié)果作為參數(shù)傳入,如下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中有個(gè)屬性argumentResolvers,是HandlerMethodArgumentResolverComposite,由類名稱可以看出使用了組合模式。RequestMappingHandlerAdapter的getDefaultArgumentResolvers,這些是默認(rèn)的參數(shù)處理器。
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所示:
圖2
DispatcherServlet的doDispatch方法中,間接調(diào)用ServletInvocableHandlerMethod的invokeAndHandle方法,之后會(huì)逐個(gè)調(diào)用HandlerMethodArgumentResolver。所以我們自定義的HandlerMethodArgumentResolver在圖2中的步驟9和步驟10處處理。如下List-3所示,遍歷所有的參數(shù),對(duì)每個(gè)參數(shù)調(diào)用HandlerMethodArgumentResolverComposite的support和resolve方法,HandlerMethodArgumentResolverComposite再委托給各個(gè)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返還的值。萬(wàn)一步驟7拋出異常,那么HandlerMethodReturnValueHandler的步驟就不會(huì)執(zhí)行,所以HandlerMethodReturnValueHandler處理不了業(yè)務(wù)代碼拋出異常的情況。
看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。