因项目中action参数过多,并且是一些通用的查询参数,所以准备进行对参数统一封装为Map对象,然后由action中传入service中进行处理,查询spring的资料发现可以通过实现HandlerMethodArgumentResolver进行数参数的绑定,参考文章《扩展SpringMVC以支持更精准的数据绑定1》进行配置后。
项目调试中发现断点不能正常进行解析器,跟踪源代码找到在org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.getArgumentResolver()方法中会获取所有已经加载的解析器,会顺序执行,而我使用的Map对象会被spring自带的解析器给处理掉,所以自定义的解析器无法进入,HandlerMethodArgumentResolverComposite关键代码:
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变量,元素内容:
[org.springfra[email protected]9dc12fc,
org.springframew[email protected]23c893fc,
org.springframework.web.s[email protected]456b97be,
org.springframework.web.serv[email protected]1ab75e8d,
org.springframework.web.ser[email protected]7ca088ae,
org.springframework.web.servle[email protected]f6d976e,
org.springframework.web.ser[email protected]63f0beab,
org.springframework.web.s[email protected]5275ffcf,
org.springframework.web.[email protected]40ed9954,
org.springfram[email protected]2eed7b19,
org.springframewo[email protected]692cbe60,
org.springframework.web.servlet[email protected]7886c691,
org.springframew[email protected]58569768,
org.springframework.web.ser[email protected]1cee5a27,
org.springframework.web.serv[email protected]6460c547,
org.springframew[email protected]d37ebcd,
org.springframework.web.servlet[email protected]5259e682,
[email protected]2c8b0b,
[email protected]c856b,
org.spr[email protected]7a3b54cf,
org.springfram[email protected]4d3d20ba,
org.springframework.web.servlet.m[email protected]682fbaf3,
[email protected],
org.springfra[email protected]6a2063e7,
org.springframework.web.ser[email protected]747f091f]
红色标注出来的RequestParamMapMethodArgumentResolver为处理Map参数的解析器,处理关键代码:
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接口的参数,所以我自定义的解析器始终无法断点进入。