在之前一篇博客中 springMVC源码分析--RequestMappingHandlerAdapter(五)我们已经简单的介绍到具体请求访问的执行某个Controller中的方法是在RequestMappingHandlerAdapter的invokeHandlerMethod方法中,其实具体执行的地方是invocableMethod.invokeAndHandle(webRequest, mavContainer);,接下来我们看看详细的执行过程。
首先是根据HandlerMethod创建ServletInvocableHandlerMethod,接下来就是调用ServletInvocableHandlerMethod的invokeAndHandle方法,其实最终是通过反射机制调用Controller中的方法。
protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
........
//创建invocableMethod
ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
........
//执行ServletInvocableHandlerMethod的invokeAndHandle方法
invocableMethod.invokeAndHandle(webRequest, mavContainer);
if (asyncManager.isConcurrentHandlingStarted()) {
return null;
}
return getModelAndView(mavContainer, modelFactory, webRequest);
}
ServletInvocableHandlerMethod中invokeAndHandle方法的调用如下,其实会调用invokeForRequest方法,并获得返回值returnValue.
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;
}
}
invokeForRequest中的操作也是比较简单的,首先获取request中的参数,然后调用doInvoke(args)方法。
public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer,
Object... providedArgs) throws Exception {
//首先会获取请求的参数,其实就是Controller方法中的参数
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());
}
//调用Controller中的方法
Object returnValue = doInvoke(args);
if (logger.isTraceEnabled()) {
logger.trace("Method [" + getMethod().getName() + "] returned [" + returnValue + "]");
}
return returnValue;
}
doInvoke方法是在InvocableHandlerMethod类中,最重要的是调用getBridgedMethod().invoke(getBean(),args),通过反射机制完成对Controller中的函数的调用。
protected Object doInvoke(Object... args) throws Exception {
ReflectionUtils.makeAccessible(getBridgedMethod());
try {
return getBridgedMethod().invoke(getBean(), args);
}
catch (IllegalArgumentException ex) {
assertTargetBean(getBridgedMethod(), getBean(), args);
throw new IllegalStateException(getInvocationErrorMessage(ex.getMessage(), args), ex);
}
catch (InvocationTargetException ex) {
// Unwrap for HandlerExceptionResolvers ...
Throwable targetException = ex.getTargetException();
if (targetException instanceof RuntimeException) {
throw (RuntimeException) targetException;
}
else if (targetException instanceof Error) {
throw (Error) targetException;
}
else if (targetException instanceof Exception) {
throw (Exception) targetException;
}
else {
String msg = getInvocationErrorMessage("Failed to invoke controller method", args);
throw new IllegalStateException(msg, targetException);
}
}
}
此外ServletInvocableHandlerMethod和InvocableHandlerMethod是HandlerMethod的子类,可以参考
springMVC源码分析--HandlerMethod中有关HandlerMethod的知识。
分享到:
相关推荐
SpringMVC ---- HelloWorld ---- 代码 SpringMVC ---- HelloWorld ---- 代码 SpringMVC ---- HelloWorld ---- 代码 SpringMVC ---- HelloWorld ---- 代码 SpringMVC ---- HelloWorld ---- 代码 SpringMVC ---- Hello...
《SpringMVC-Mybatis-Shiro-Redis:构建安全高效的Web应用》 在现代Web开发中,构建一个高效且安全的后端系统是至关重要的。本文将深入探讨一个基于SpringMVC、Mybatis、Shiro和Redis的Web应用架构,这四个组件共同...
基于SpringMVC Mybatis Shiro Redis 的权限管理系统,该系统已经部署到线上,线上访问地址:http://shiro.itboy.net,登录账号:admin 密码:sojson,,详细教程参考sojson.com/shiro
【标题】"SpringMVC-Mybatis-Shiro-redis-master" 涉及的是一个集成框架项目,这个项目集成了四个关键的技术组件:SpringMVC、MyBatis、Shiro和Redis。这些技术在现代Java Web开发中扮演着重要角色。 **SpringMVC**...
SpringMVC是一个强大的Java web应用程序框架,用于处理HTTP请求和响应。它主要负责视图控制器的职责,使得业务逻辑和视图分离。而Spring Data Redis是Spring Framework的一个模块,专门用于简化与Redis键值存储系统...
springMvc源码分析springMvc源码分析springMvc源码分析springMvc源码分析springMvc源码分析springMvc源码分析
而SpringMVC作为后端强大的MVC框架,能够有效地处理请求和响应,提供数据支持。本文将深入探讨如何利用EasyUI的Tree组件与SpringMVC进行整合,实现前端与后端的交互。 一、EasyUI Tree组件介绍 EasyUI的Tree组件...
SpringMVC和JAX-RS是两种在Java世界中广泛使用的Web开发框架,它们都用于构建RESTful服务,但有着不同的设计哲学和技术实现。这个压缩包"SpringMVC精品资源--JAX-RS & SpringMVC supported maven build.zip"显然是一...
SpringMVC4教程-.pptx SpringMVC4教程-.pptx SpringMVC4教程-.pptx SpringMVC4教程-.pptx SpringMVC4教程-.pptx
在 "springmvc-base-input-02" 这个项目中,我们很可能会看到如何处理用户输入和请求的进阶知识。 在 Spring MVC 中,`pom.xml` 文件是 Maven 项目的配置文件,它定义了项目的依赖关系。在这个项目中,`pom.xml` ...
通过分析这个"springmvc-maven-webapp-helloworld"项目,我们可以深入理解每个组件的作用,以及它们如何协同工作来构建一个完整的Web应用程序。同时,这也是一个很好的起点,可以帮助开发者逐步掌握SpringMVC、Maven...
《SpringMVC-Mybatis-Shiro-Redis整合实践详解》 在现代Web开发中,...通过分析源码,开发者可以深入理解每个组件的功能以及它们如何协同工作,从而在自己的项目中更好地应用这些技术,提升项目的质量和效率。
本资料"springmvc-high-other-05.rar"着重探讨了SpringMVC的一些高级特性和用法,特别是那些不太常见但对提升应用性能和可维护性至关重要的特性。 1. **POM.xml配置解析**:在"pom.xml"文件中,我们可以看到项目...
基于springboot+springmvc+mybatis-plus的微信小程序美容预约平台源码.zip本资源中的源码都是经过本地编译过可运行的,评审分达到95分以上。资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、...
【标题】"SpringMVC精品资源--JAX-RS & SpringMVC supported gradle bui.zip" 提供的是一份关于使用Gradle构建支持JAX-RS和SpringMVC的项目资源。这涉及到两个关键的技术栈:SpringMVC,一个用于构建Web应用程序的...
在实际开发中,SpringMVC和Mybatis的组合能够提供高效的Web服务和灵活的数据访问。例如,SpringMVC可以与RESTful API设计相结合,实现前后端分离;Mybatis则可以配合Mybatis-Plus扩展,进一步简化CRUD操作。通过深入...
【标题】"maven-springmvc-mybatis-memcached"是一个基于Maven、SpringMVC、MyBatis和Memcached的项目示例。这个项目整合了这些技术,为开发高效、可扩展的Web应用程序提供了基础架构。 【描述】"maven-springmvc-...
SpringMVC文件上传war包
在这个名为"springmvc-login-interceptor"的项目中,我们关注的核心是Spring MVC的拦截器(Interceptor)功能,它允许开发者在请求被控制器处理之前或之后执行自定义逻辑。拦截器在实际应用中常用于权限验证、日志...
在 `SpringMVC-demo - examples` 这个项目中,我们可以通过一系列示例来深入理解 `SpringMVC` 的核心特性。 1. **配置与初始化** 在 `SpringMVC` 中,我们通常使用 `web.xml` 配置文件进行初始化设置,声明 `...