springmvc为请求处理器的目标参数赋值的过程

↓在invokeHandlerMethod()方法中调用resolveHandlerArguments()方法↓

Object[] args = resolveHandlerArguments(handlerMethodToInvoke, handler, webRequest, implicitModel);

↓在resolveHandlerArguments()方法中↓

1. 创建 WebDataBinder 对象

WebDataBinder binder = resolveModelAttribute(attrName, methodParam, implicitModel, webRequest, handler);

↓进入resolveModelAttribute()方法↓

(1). 确定 objectName 属性: 若传入的 attrName 属性值为 “”, 则 objectName 为类名第一个字母小写

    注意: attrName. 若目标方法的 POJO 属性使用了 @ModelAttribute 来修饰, 则 attrName 值即为 @ModelAttribute的 value 属性值 
// Bind request parameter onto object...
String name = attrName;
if ("".equals(name)) {
    name = Conventions.getVariableNameForParameter(methodParam);
}

(2). 确定 target 属性

1> 在 implicitModel 中查找 attrName 对应的属性值. 若存在, ok

Object bindObject;
if (implicitModel.containsKey(name)) {
    bindObject = implicitModel.get(name);
}

2> 若不存在: 则验证当前 Handler 是否使用了 @SessionAttributes 进行修饰, 若使用了, 则尝试从 Session 中获取 attrName 所对应的属性值. 若 session 中没有对应的属性值, 则抛出了异常.

else if (this.methodResolver.isSessionAttribute(name, paramType)) {
    bindObject = this.sessionAttributeStore.retrieveAttribute(webRequest, name);
    if (bindObject == null) {
        raiseSessionRequiredException("Session attribute '" + name + "' required - not found in session");
    }
}

3> 若 Handler 没有使用 @SessionAttributes 进行修饰, 或 @SessionAttributes 中没有使用 value 值指定的 key和 attrName 相匹配, 则通过反射创建了 POJO 对象

else {
    bindObject = BeanUtils.instantiateClass(paramType);
}

(3). 创建WebDataBinder 对象

WebDataBinder binder = createBinder(webRequest, bindObject, name);

返回一个WebDataBinder 对象

initBinder(handler, name, binder, webRequest);
return binder;

↓返回到resolveHandlerArguments()方法中↓

2. SpringMVC 把表单的请求参数赋给了 WebDataBinder 的 target 对应的属性

if (binder.getTarget() != null) {
    doBind(binder, webRequest, validate, validationHints, !assignBindingResult);
}

3.从WebDataBinder中取出target

args[i] = binder.getTarget();

4. SpringMVC 会把 WebDataBinder 的 attrName 和 target 给到 implicitModel,进而传到 request 域对象中

implicitModel.putAll(binder.getBindingResult().getModel());

↓返回到invokeHandlerMethod()方法中↓

5. 把 WebDataBinder 的 target 即resolveHandlerArguments()方法返回的参数args传递给目标方法的入参

Object[] args = resolveHandlerArguments(handlerMethodToInvoke, handler, webRequest, implicitModel);
handlerMethodToInvoke.invoke(handler, args);

你可能感兴趣的:(springmvc,spring,mvc)