转载 https://blog.csdn.net/qq924862077/article/details/54177442
HandlerMethodArgumentResolver是用来为处理器解析参数的,主要用在HandlerMethod中,每个Resolver对应一种类型的参数,其实现类特别的多。
HandlerMethodArgumentResolver接口及其实现类如下:
HandlerMethodArgumentResolver的接口定义如下:
(1)supportsParameter 用于判断是否支持对某种参数的解析
(2)resolveArgument 将请求中的参数值解析为某种对象
public interface HandlerMethodArgumentResolver {
/**
* Whether the given {@linkplain MethodParameter method parameter} is
* supported by this resolver.
* @param parameter the method parameter to check
* @return {@code true} if this resolver supports the supplied parameter;
* {@code false} otherwise
*/
//判断是否支持某种类型的函数参数
boolean supportsParameter(MethodParameter parameter);
/**
* Resolves a method parameter into an argument value from a given request.
* A {@link ModelAndViewContainer} provides access to the model for the
* request. A {@link WebDataBinderFactory} provides a way to create
* a {@link WebDataBinder} instance when needed for data binding and
* type conversion purposes.
* @param parameter the method parameter to resolve. This parameter must
* have previously been passed to
* {@link #supportsParameter(org.springframework.core.MethodParameter)}
* and it must have returned {@code true}
* @param mavContainer the ModelAndViewContainer for the current request
* @param webRequest the current request
* @param binderFactory a factory for creating {@link WebDataBinder} instances
* @return the resolved argument value, or {@code null}.
* @throws Exception in case of errors with the preparation of argument values
*/
//解析请求中的参数为某个函数的参数对象
Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception;
}
HandlerMethodArgumentResolver的执行流程:
参数的处理是在InvocableHandlerMethod中,当执行具体的请求处理时执行invokeForRequest函数
public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
//获取执行Controller的函数的参数对象
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
......
}
具体的参数解析器的选择和使用参数解析器去解析参数的实现都在getMethodArgumentValues中,首先springMVC在启动时会将所有的参数解析器放到HandlerMethodArgumentResolverComposite,HandlerMethodArgumentResolverComposite是所有参数的一个集合,接下来就是从HandlerMethodArgumentResolverComposite参数解析器集合中选择一个支持对parameter解析的参数解析器,接下来就使用支持参数解析的解析器进行参数解析。
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);
GenericTypeResolver.resolveParameterType(parameter, getBean().getClass());
//获取参数值对象
args[i] = resolveProvidedArgument(parameter, providedArgs);
if (args[i] != null) {
continue;
}
//首先判断是否有参数解析器支持参数parameter,采用职责链的设计模式
if (this.argumentResolvers.supportsParameter(parameter)) {
try {
//如果参数解析器支持解析参数parameter,那么解析参数成Controller的函数需要的格式
args[i] = this.argumentResolvers.resolveArgument(
parameter, mavContainer, request, this.dataBinderFactory);
continue;
}
catch (Exception ex) {
if (logger.isDebugEnabled()) {
logger.debug(getArgumentResolutionErrorMessage("Error resolving argument", i), ex);
}
throw ex;
}
}
if (args[i] == null) {
String msg = getArgumentResolutionErrorMessage("No suitable resolver for argument", i);
throw new IllegalStateException(msg);
}
}
//返回参数值
return args;
}