SpringMVC源码之参数解析绑定原理 (2)

先看一个简单参数绑定,有如下Controller和请求,代码如下。

@Controller @RequestMapping("/ParameterBind") public class ParameterBindTestController { @ResponseBody @RequestMapping("/test1") public String test1(int id){ System.out.println(id); return "test1"; } }

请求进入DispatcherServlet的doDispatch后,获取HandlerMethod。然后根据HandlerMethod来确认HandlerApapter,确认后执行HandlerAdapter的handle方法。这里确认HandlerApater为RequestMappingHandlerAdapter,在执行handlerMethod之前,需要处理参数的绑定。然后看看详细的参数绑定过程

执行HandlerAdapter的handler方法后,进入RequestMappingHandlerAdapter的invokeHandleMethod方法(line:711)

private ModelAndView invokeHandleMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception { ServletWebRequest webRequest = new ServletWebRequest(request, response); WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod); ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory); //根据handlerMethod和binderFactory创建一个ServletInvocableHandlerMethod。后续把请求直接交给ServletInvocableHandlerMethod执行。 //createRequestMappingMethod方法比较简单,把之前RequestMappingHandlerAdapter初始化的argumentResolvers和returnValueHandlers添加至ServletInvocableHandlerMethod中 ServletInvocableHandlerMethod requestMappingMethod = createRequestMappingMethod(handlerMethod, binderFactory); ModelAndViewContainer mavContainer = new ModelAndViewContainer(); mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request)); modelFactory.initModel(webRequest, mavContainer, requestMappingMethod); mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect); AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response); asyncWebRequest.setTimeout(this.asyncRequestTimeout); final WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); asyncManager.setTaskExecutor(this.taskExecutor); asyncManager.setAsyncWebRequest(asyncWebRequest); asyncManager.registerCallableInterceptors(this.callableInterceptors); asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors); if (asyncManager.hasConcurrentResult()) { Object result = asyncManager.getConcurrentResult(); mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0]; asyncManager.clearConcurrentResult(); if (logger.isDebugEnabled()) { logger.debug("Found concurrent result value [" + result + "]"); } requestMappingMethod = requestMappingMethod.wrapConcurrentResult(result); } requestMappingMethod.invokeAndHandle(webRequest, mavContainer); if (asyncManager.isConcurrentHandlingStarted()) { return null; } return getModelAndView(mavContainer, modelFactory, webRequest); }

然后进入invokeAndHanldle方法,然后进入invokeForRequest方法,这个方法的职责是从request中解析出HandlerMethod方法所需要的参数,然后通过反射调用HandlerMethod中的method。代码如下

public final Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { //从request中解析出HandlerMethod方法所需要的参数,并返回Object[] Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs); if (logger.isTraceEnabled()) { StringBuilder builder = new StringBuilder("Invoking ["); builder.append(this.getMethod().getName()).append("] method with arguments "); builder.append(Arrays.asList(args)); logger.trace(builder.toString()); } //通过反射执行HandleMethod中的method,方法参数为args。并返回方法执行的返回值 Object returnValue = invoke(args); if (logger.isTraceEnabled()) { logger.trace("Method [" + this.getMethod().getName() + "] returned [" + returnValue + "]"); } return returnValue; }

直接进入getMethodArgumentValues方法看看其过程,代码如下

/** * 获取当前请求的方法参数值。 */ private Object[] getMethodArgumentValues( NativeWebRequest request, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { //获取方法参数数组 MethodParameter[] parameters = getMethodParameters(); //创建一个参数数组,保存从request解析出的方法参数 Object[] args = new Object[parameters.length]; for (int i = 0; i < parameters.length; i++) { MethodParameter parameter = parameters[i]; parameter.initParameterNameDiscovery(parameterNameDiscoverer); GenericTypeResolver.resolveParameterType(parameter, getBean().getClass()); args[i] = resolveProvidedArgument(parameter, providedArgs); if (args[i] != null) { continue; } //判断之前RequestMappingHandlerAdapter初始化的那24个HandlerMethodArgumentResolver(参数解析器),是否存在支持该参数解析的解析器 if (argumentResolvers.supportsParameter(parameter)) { try { args[i] = argumentResolvers.resolveArgument(parameter, mavContainer, request, dataBinderFactory); continue; } catch (Exception ex) { if (logger.isTraceEnabled()) { logger.trace(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; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wspsgp.html