`
king_tt
  • 浏览: 2246715 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

springMVC源码分析--访问请求执行ServletInvocableHandlerMethod和InvocableHandlerMethod

 
阅读更多

在之前一篇博客中 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 ---- HelloWorld ---- 代码 SpringMVC ---- Hello...

    SpringMVC-Mybatis-Shiro-redis

    《SpringMVC-Mybatis-Shiro-Redis:构建安全高效的Web应用》 在现代Web开发中,构建一个高效且安全的后端系统是至关重要的。本文将深入探讨一个基于SpringMVC、Mybatis、Shiro和Redis的Web应用架构,这四个组件共同...

    SpringMVC-Mybatis-Shiro-redis-0.2-master

    基于SpringMVC Mybatis Shiro Redis 的权限管理系统,该系统已经部署到线上,线上访问地址:http://shiro.itboy.net,登录账号:admin 密码:sojson,,详细教程参考sojson.com/shiro

    SpringMVC-Mybatis-Shiro-redis-master

    【标题】"SpringMVC-Mybatis-Shiro-redis-master" 涉及的是一个集成框架项目,这个项目集成了四个关键的技术组件:SpringMVC、MyBatis、Shiro和Redis。这些技术在现代Java Web开发中扮演着重要角色。 **SpringMVC**...

    springMVC集成spring-data-redis

    SpringMVC是一个强大的Java web应用程序框架,用于处理HTTP请求和响应。它主要负责视图控制器的职责,使得业务逻辑和视图分离。而Spring Data Redis是Spring Framework的一个模块,专门用于简化与Redis键值存储系统...

    springMvc源码分析

    springMvc源码分析springMvc源码分析springMvc源码分析springMvc源码分析springMvc源码分析springMvc源码分析

    easyUI-springmvc-tree-demo

    而SpringMVC作为后端强大的MVC框架,能够有效地处理请求和响应,提供数据支持。本文将深入探讨如何利用EasyUI的Tree组件与SpringMVC进行整合,实现前端与后端的交互。 一、EasyUI Tree组件介绍 EasyUI的Tree组件...

    SpringMVC精品资源--JAX-RS & SpringMVC supported maven buil.zip

    SpringMVC和JAX-RS是两种在Java世界中广泛使用的Web开发框架,它们都用于构建RESTful服务,但有着不同的设计哲学和技术实现。这个压缩包"SpringMVC精品资源--JAX-RS & SpringMVC supported maven build.zip"显然是一...

    SpringMVC4教程-.pptx

    SpringMVC4教程-.pptx SpringMVC4教程-.pptx SpringMVC4教程-.pptx SpringMVC4教程-.pptx SpringMVC4教程-.pptx

    springmvc-base-input-02.rar

    在 "springmvc-base-input-02" 这个项目中,我们很可能会看到如何处理用户输入和请求的进阶知识。 在 Spring MVC 中,`pom.xml` 文件是 Maven 项目的配置文件,它定义了项目的依赖关系。在这个项目中,`pom.xml` ...

    springmvc-maven-webapp-helloworld 源码

    通过分析这个"springmvc-maven-webapp-helloworld"项目,我们可以深入理解每个组件的作用,以及它们如何协同工作来构建一个完整的Web应用程序。同时,这也是一个很好的起点,可以帮助开发者逐步掌握SpringMVC、Maven...

    SpringMVC-Mybatis-Shiro-redis-0.2_baichengzhou.tar.gz

    《SpringMVC-Mybatis-Shiro-Redis整合实践详解》 在现代Web开发中,...通过分析源码,开发者可以深入理解每个组件的功能以及它们如何协同工作,从而在自己的项目中更好地应用这些技术,提升项目的质量和效率。

    springmvc-high-other-05.rar

    本资料"springmvc-high-other-05.rar"着重探讨了SpringMVC的一些高级特性和用法,特别是那些不太常见但对提升应用性能和可维护性至关重要的特性。 1. **POM.xml配置解析**:在"pom.xml"文件中,我们可以看到项目...

    基于springboot+springmvc+mybatis-plus的微信小程序美容预约平台源码.zip

    基于springboot+springmvc+mybatis-plus的微信小程序美容预约平台源码.zip本资源中的源码都是经过本地编译过可运行的,评审分达到95分以上。资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、...

    SpringMVC精品资源--JAX-RS & SpringMVC supported gradle bui.zip

    【标题】"SpringMVC精品资源--JAX-RS & SpringMVC supported gradle bui.zip" 提供的是一份关于使用Gradle构建支持JAX-RS和SpringMVC的项目资源。这涉及到两个关键的技术栈:SpringMVC,一个用于构建Web应用程序的...

    SpringMVC精品资源--SpringMVC+Mybatis 脚手架.zip

    在实际开发中,SpringMVC和Mybatis的组合能够提供高效的Web服务和灵活的数据访问。例如,SpringMVC可以与RESTful API设计相结合,实现前后端分离;Mybatis则可以配合Mybatis-Plus扩展,进一步简化CRUD操作。通过深入...

    maven-springmvc-mybatis-memcached

    【标题】"maven-springmvc-mybatis-memcached"是一个基于Maven、SpringMVC、MyBatis和Memcached的项目示例。这个项目整合了这些技术,为开发高效、可扩展的Web应用程序提供了基础架构。 【描述】"maven-springmvc-...

    springmvc_exception-1.0-SNAPSHOT.war

    SpringMVC文件上传war包

    springmvc-login-interceptor

    在这个名为"springmvc-login-interceptor"的项目中,我们关注的核心是Spring MVC的拦截器(Interceptor)功能,它允许开发者在请求被控制器处理之前或之后执行自定义逻辑。拦截器在实际应用中常用于权限验证、日志...

    SpringMVC-demo - examples

    在 `SpringMVC-demo - examples` 这个项目中,我们可以通过一系列示例来深入理解 `SpringMVC` 的核心特性。 1. **配置与初始化** 在 `SpringMVC` 中,我们通常使用 `web.xml` 配置文件进行初始化设置,声明 `...

Global site tag (gtag.js) - Google Analytics