因項目中action參數過多,而且是一些通用的查詢參數,因此準備進行對參數統一封裝爲Map對象,而後由action中傳入service中進行處理,查詢spring的資料發現能夠經過實現HandlerMethodArgumentResolver進行數參數的綁定,參考文章《擴展SpringMVC以支持更精準的數據綁定1》進行配置後。web
項目調試中發現斷點不能正常進行解析器,跟蹤源代碼找到在org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.getArgumentResolver()方法中會獲取全部已經加載的解析器,會順序執行,而我使用的Map對象會被spring自帶的解析器給處理掉,因此自定義的解析器沒法進入,HandlerMethodArgumentResolverComposite關鍵代碼:spring
private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) { HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter); if (result == null) { for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) { if (logger.isTraceEnabled()) { logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" + parameter.getGenericParameterType() + "]"); } if (methodArgumentResolver.supportsParameter(parameter)) { result = methodArgumentResolver; this.argumentResolverCache.put(parameter, result); break; } } } return result; }
其中this.argumentResolvers爲LinkedList變量,元素內容:mvc
[org.springframework.web.method.annotation.RequestParamMethodArgumentResolver@9dc12fc,
org.springframework.web.method.annotation.RequestParamMapMethodArgumentResolver@23c893fc,
org.springframework.web.servlet.mvc.method.annotation.PathVariableMethodArgumentResolver@456b97be,
org.springframework.web.servlet.mvc.method.annotation.PathVariableMapMethodArgumentResolver@1ab75e8d,
org.springframework.web.servlet.mvc.method.annotation.MatrixVariableMethodArgumentResolver@7ca088ae,
org.springframework.web.servlet.mvc.method.annotation.MatrixVariableMapMethodArgumentResolver@f6d976e,
org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor@63f0beab,
org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor@5275ffcf,
org.springframework.web.servlet.mvc.method.annotation.RequestPartMethodArgumentResolver@40ed9954,
org.springframework.web.method.annotation.RequestHeaderMethodArgumentResolver@2eed7b19,
org.springframework.web.method.annotation.RequestHeaderMapMethodArgumentResolver@692cbe60,
org.springframework.web.servlet.mvc.method.annotation.ServletCookieValueMethodArgumentResolver@7886c691,
org.springframework.web.method.annotation.ExpressionValueMethodArgumentResolver@58569768,
org.springframework.web.servlet.mvc.method.annotation.ServletRequestMethodArgumentResolver@1cee5a27,
org.springframework.web.servlet.mvc.method.annotation.ServletResponseMethodArgumentResolver@6460c547,
org.springframework.web.servlet.mvc.method.annotation.HttpEntityMethodProcessor@d37ebcd,
org.springframework.web.servlet.mvc.method.annotation.RedirectAttributesMethodArgumentResolver@5259e682,
org.springframework.web.method.annotation.ModelMethodProcessor@c2c8b0b,
org.springframework.web.method.annotation.MapMethodProcessor@405c856b,
org.springframework.web.method.annotation.ErrorsMethodArgumentResolver@7a3b54cf,
org.springframework.web.method.annotation.SessionStatusMethodArgumentResolver@4d3d20ba,
org.springframework.web.servlet.mvc.method.annotation.UriComponentsBuilderMethodArgumentResolver@682fbaf3,
com.catt.web.springmvc.RequestMapResolver@159adcf5,
org.springframework.web.method.annotation.RequestParamMethodArgumentResolver@6a2063e7,
org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor@747f091f]ui
紅色標註出來的RequestParamMapMethodArgumentResolver爲處理Map參數的解析器,處理關鍵代碼:this
public boolean supportsParameter(MethodParameter parameter) { RequestParam requestParamAnnot = parameter.getParameterAnnotation(RequestParam.class); if (requestParamAnnot != null) { if (Map.class.isAssignableFrom(parameter.getParameterType())) { return !StringUtils.hasText(requestParamAnnot.value()); } } return false; }
Map.class.isAssignableFrom會攔截實現Map接口的參數,因此我自定義的解析器始終沒法斷點進入。