Object… providedArgs) throws Exception {
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
if (logger.isTraceEnabled()) {
logger.trace("Arguments: " + Arrays.toString(args));
}
return doInvoke(args);
}
复制代码
可以看出,这里面通过getMethodArgumentValues
方法处理参数,然后调用doInvoke
方法获取返回值。
继续深入,能够找到org.springframework.web.method.annotation.RequestParamMethodArgumentResolver#resolveArgument
方法,这个方法就是解析参数的逻辑。
试想一下,如果是我们自己实现这段逻辑,会怎么做呢?
-
获取输入参数
-
找到目标参数
-
检查是否需要特殊转换逻辑
-
如果需要,进行转换
-
如果不需要,直接返回
获取输入参数的逻辑在org.springframework.web.method.annotation.RequestParamMethodArgumentResolver#resolveName
,单参数返回的是 String 类型,多参数返回 String 数组。核心代码如下:
String[] paramValues = request.getParameterValues(name);
if (paramValues != null) {
arg = (paramValues.length == 1 ? paramValues[0] : paramValues);
}
复制代码
所以说,无论我们的目标参数是什么,输入参数都是 String 类型或 String 数组,然后 Spring 把它们转换为我们期望的类型。
找到目标参数的逻辑在DispatcherServlet
中,根据 uri 找到对应的 Controller 处理方法,找到方法就找到了目标参数类型。
接下来就是检查是否需要转换逻辑,也就是org.springframework.validation.DataBinder#convertIfNecessary
,顾名思义,如果需要就转换,将字符串类型转换为目标类型。在我们的例子中,就是将 String 转换为枚举值。
查找转换器
继续深扒,会在org.springframework.beans.TypeConverterDelegate#convertIfNecessary
方法中找到这么一段逻辑:
if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) {
try {
return (T) conversionService.convert(newValue, sourceTypeDesc, typeDescriptor);
}
cat