萌新学习SpringMVC (3)

找拦截器大概也是上面的一个过程,于是我们就可以顺利拿到HandlerExecutionChain了,找到HandlerExecutionChain后,我们是先去拿对应的HandlerAdaptor。我们也去看看里边做了什么:

// 遍历HandlerAdapter实例,找到个合适的返回 protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { for (HandlerAdapter ha : this.handlerAdapters) { if (ha.supports(handler)) { return ha; } } }

我们看一个常用HandlerAdapter实例RequestMappingHandlerAdapter,会发现他会初始化很多的参数解析器,其实我们经常用的@ResponseBody解析器就被内置在里边:

private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() { List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>(); resolvers.add(new MatrixVariableMethodArgumentResolver()); resolvers.add(new MatrixVariableMapMethodArgumentResolver()); resolvers.add(new ServletModelAttributeMethodProcessor(false)); // ResponseBody Requestbody解析器 resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice)); resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), t // 等等 return resolvers; }

得到HandlerAdaptor后,随之而行的就是拦截器的前置处理,然后就是真实的mv = ha.handle(processedRequest, response, mappedHandler.getHandler())。

这里边嵌套了好几层,我就不一一贴代码了,我们会进入ServletInvocableHandlerMethod#invokeAndHandle方法,我们看一下这里边做了什么:

public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { // 处理请求 Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs); setResponseStatus(webRequest); if (returnValue == null) { if (isRequestNotModified(webRequest) || hasResponseStatus() || mavContainer.isRequestHandled()) { mavContainer.setRequestHandled(true); return; } } //.. mavContainer.setRequestHandled(false); try { // 处理返回值 this.returnValueHandlers.handleReturnValue( returnValue, getReturnValueType(returnValue), mavContainer, webRequest); } }

处理请求的方法我们进去看看invokeForRequest

public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { // 得到参数 Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs); // 调用方法 Object returnValue = doInvoke(args); if (logger.isTraceEnabled()) { logger.trace("Method [" + getMethod().getName() + "] returned [" + returnValue + "]"); } return returnValue; }

我们看看它是怎么处理参数的,getMethodArgumentValues方法进去看看:

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; } // 找到适配的参数解析器 if (this.argumentResolvers.supportsParameter(parameter)) { try { args[i] = this.argumentResolvers.resolveArgument( parameter, mavContainer, request, this.dataBinderFactory); continue; } //..... } return args; }

这些参数解析器实际上在HandlerAdaptor内置的那些,这里不好放代码,所以我截个图吧:

萌新学习SpringMVC

针对于RequestResponseBodyMethodProcessor解析器我们看看里边做了什么:

public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { // 通过Converters对参数转换 Object arg = readWithMessageConverters(webRequest, parameter, parameter.getGenericParameterType()); String name = Conventions.getVariableNameForParameter(parameter); WebDataBinder binder = binderFactory.createBinder(webRequest, arg, name); // ... mavContainer.addAttribute(BindingResult.MODEL_KEY_PREFIX + name, binder.getBindingResult()); return arg; }

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

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