【spring-mvc】spring-mvc中handlerMethod的执行
2016-02-17 18:14
483 查看
今天来聊聊spring-mvc是如何来执行Controller中的method的。
spring-mvc默认的HandlerAdapter是RequestMappingHandlerAdapter,
DispatcherServlet将处理逻辑交由HandlerAdapter,而HandlerAdapter,由交给ServletInvocableHandlerMethod来invokeAndHandle.requestMappingMethod.invokeAndHandle(webRequest, mavContainer);
跟踪源代码
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; } } else if (StringUtils.hasText(this.responseReason)) { mavContainer.setRequestHandled(true); return; } mavContainer.setRequestHandled(false); try { this.returnValueHandlers.handleReturnValue( returnValue, getReturnValueType(returnValue), mavContainer, webRequest); } catch (Exception ex) { if (logger.isTraceEnabled()) { logger.trace(getReturnValueHandlingErrorMessage("Error handling return value", returnValue), ex); } throw ex; } }
主要是
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs)整个执行过程都在这步代码中,那么到底是如何处理的。
public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs); if (logger.isTraceEnabled()) { StringBuilder sb = new StringBuilder("Invoking ["); sb.append(getBeanType().getSimpleName()).append("."); sb.append(getMethod().getName()).append("] method with arguments "); sb.append(Arrays.asList(args)); logger.trace(sb.toString()); } Object returnValue = doInvoke(args); if (logger.isTraceEnabled()) { logger.trace("Method [" + getMethod().getName() + "] returned [" + returnValue + "]"); } return returnValue; }
我们知道利用反射来执行一个方法的时候,我们需要入参。那么
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);就是获取Controller的入参。也就是需要用到参数解析了,spring-mvc为我们提供了强大的数据绑定机制,
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; } //argumentResolvers是RequestMappingHandlerAdapter传过来的参数解析器。 //这里是循环遍历,查找能够解析该参数的 if (this.argumentResolvers.supportsParameter(parameter)) { try { args[i] = this.argumentResolvers.resolveArgument( parameter, mavContainer, request, this.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; }
下一步就是找到参数解析器来解析该参数了 。spring-mvc为我们提供了23种参数解析器。这里就不一一介绍了,
得到参数之后,然后调用
Object returnValue = doInvoke(args);得到执行的返回结果。
this.returnValueHandlers.handleReturnValue( returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
下面的处理逻辑:如果是视图,就调用ViewResolver,render出jsp,如何是JSON。则用response写到应用。
相关文章推荐
- Java中的Copy-On-Write容器,CopyOnWriteArrayList和CopyOnWriteArraySet
- 在用mvn编译java文件时遇到问题
- AndroidStudio导入Eclipse项目并保留Eclipse目录结构
- zyUpload结合SpringMVC实现批量图片的上传
- Struts2-1.配置&与第一个应用
- JAVA NIO复习笔记
- Java配置文件Properties的读取、写入与更新操作
- 一个纠结的转换!
- MyEclipse中jsp的凝视报错解决
- Java 序列化Serializable
- java(看程序写结果)
- eclipse问题
- Java基础——常用类(Date、File)以及包装类
- Spring的JdbcTemplate与其事务
- Spring:源码解读Spring IOC原理
- java基础-jdbc
- 全面分析 Spring 的编程式事务管理及声明式事务管理
- eclipse 部署没有 classes包的问题!
- JAVA_JCF(Java Collection Framework)学习笔记(四)
- SpringMVC中注解控制器及数据绑定