dispatcherServletController参数填充源码

来源:互联网 发布:mac用的播放器 编辑:程序博客网 时间:2024/05/24 22:43

关于dispatcherServlet的源码,很多人都看过,但有些具体的细节,可能没有专心研究过,楼主遇到了一个参数默认填充的问题,所以研究了下源码。问题如下:


@RequestMapping("/addgoods")    public void addGoods(GoodsMaster goodsMaster,GoodsSlave goodsSlave,HttpServletRequest request) {

当我们写一个Controller方法的时候,springmvc会帮我们填充,GoodsMaster,GoodsSlave等自己定义的类,只要jsp中的name与类中的属性对应上。

那么dispatcherservlet是怎么做的呢,在doDispatcher()方法中,

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
在这里,然后继续,进入handle方法最后一行,如下

return invokeHandlerMethod(request, response, handler);跟进去:
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {ServletHandlerMethodResolver methodResolver = getMethodResolver(handler);Method handlerMethod = methodResolver.resolveHandlerMethod(request);ServletHandlerMethodInvoker methodInvoker = new ServletHandlerMethodInvoker(methodResolver);ServletWebRequest webRequest = new ServletWebRequest(request, response);ExtendedModelMap implicitModel = new BindingAwareModelMap();Object result = methodInvoker.invokeHandlerMethod(handlerMethod, handler, webRequest, implicitModel);ModelAndView mav =methodInvoker.getModelAndView(handlerMethod, handler.getClass(), result, implicitModel, webRequest);methodInvoker.updateModelAttributes(handler, (mav != null ? mav.getModel() : null), implicitModel, webRequest);return mav;}

重点是标黑的这行,进去,有这样一行代码:
Object[] args = this.resolveHandlerArguments(handlerMethodToInvoke, handler, webRequest, implicitModel);
在这个方法中,会获取你的参数类型,然后反射填充你的参数中的所有属性。

else if (attrName != null) {WebDataBinder binder =resolveModelAttribute(attrName, methodParam, implicitModel, webRequest, handler);boolean assignBindingResult = (args.length > i + 1 && Errors.class.isAssignableFrom(paramTypes[i + 1]));if (binder.getTarget() != null) {doBind(binder, webRequest, validate, validationHints, !assignBindingResult);}args[i] = binder.getTarget();if (assignBindingResult) {args[i + 1] = binder.getBindingResult();i++;}implicitModel.putAll(binder.getBindingResult().getModel());}

加粗的这行进行了,反射与参数填充。如下
private WebDataBinder resolveModelAttribute(String attrName, MethodParameter methodParam,ExtendedModelMap implicitModel, NativeWebRequest webRequest, Object handler) throws Exception {// Bind request parameter onto object...String name = attrName;if ("".equals(name)) {name = Conventions.getVariableNameForParameter(methodParam);}Class<?> paramType = methodParam.getParameterType();Object bindObject;if (implicitModel.containsKey(name)) {bindObject = implicitModel.get(name);}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");}}else {bindObject = BeanUtils.instantiateClass(paramType);}WebDataBinder binder = createBinder(webRequest, bindObject, name);initBinder(handler, name, binder, webRequest);return binder;}