Spring中HandlerMethod类源码详细解析

 更新时间:2023年11月18日 09:54:18   作者:立小研先森  
这篇文章主要介绍了Spring中HandlerMethod类源码详细解析,HandlerMethod类用于封装控制器方法信息,包含类信息、方法Method对象、参数、注解等信息,具体的接口请求是可以根据封装的信息调用具体的方法来执行业务逻辑,需要的朋友可以参考下

HandlerMethod类

HandlerMethod类用于封装控制器方法信息,包含类信息、方法Method对象、参数、注解等信息,具体的接口请求是可以根据封装的信息调用具体的方法来执行业务逻辑;

HandlerMethod有三个子类分别是InvocableHandlerMethod、ServletInvocableHandlerMethod、ConcurrentResultHandlerMethod,类的关系图如下:

在这里插入图片描述

1.HandlerMethod类源码详解

public class HandlerMethod {
	//bean名称,调试的时候看到是字符串控制器名称(首字母小写)
	private final Object bean;
  //bean工厂类,个人调试传入的是DefaultListableBeanFactory
	@Nullable
	private final BeanFactory beanFactory;
	//方法所属类
	private final Class<?> beanType;
	//控制器方法
	private final Method method;
	//桥接方法,如果method是原生的,这个属性就是method
	private final Method bridgedMethod;
	//封装方法参数实例
	private final MethodParameter[] parameters;
	//Http状态码
	@Nullable
	private HttpStatus responseStatus;
	//ResponseStatus注解的reason值
	@Nullable
	private String responseStatusReason;
	//使用createWithResolvedBean方法创建的HttpMethod方法对象
	@Nullable
	private HandlerMethod resolvedFromHandlerMethod;
	//getInterfaceParameterAnnotations获取
	@Nullable
	private volatile List<Annotation[][]> interfaceParameterAnnotations;
	//类描述,使用initDescription方法解析beanType和method获得
	private final String description;
}

2.InvocableHandlerMethod类详解

InvocableHandlerMethod类是HandlerMethod的直接子类,该类中新增了对请求参数解析的参数解析程序,request请求时的回调方法invokeForRequest和doInvoke(建议阅读HandlerAdapter源码解析)

request请求会在RequestMappingHandlerAdapter类中的handleInternal方法进行回调,回调方法的源码如下:

	/**
	* 获取request请求参数,调用控制器方法
	**/
  @Nullable
	public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
			Object... providedArgs) throws Exception {
		//获取request请求方法的参数
		Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
		if (logger.isTraceEnabled()) {
			logger.trace("Arguments: " + Arrays.toString(args));
		}
		return doInvoke(args);
	}

doInvoke方法源码:

	/**
	* 使用给定的参数调用控制器方法
	**/
	@Nullable
	protected Object doInvoke(Object... args) throws Exception {
		ReflectionUtils.makeAccessible(getBridgedMethod());
		try {
      //调用真实最终的控制器方法,并返回执行后的结果
			return getBridgedMethod().invoke(getBean(), args);
		}
		catch (IllegalArgumentException ex) {
			assertTargetBean(getBridgedMethod(), getBean(), args);
			String text = (ex.getMessage() != null ? ex.getMessage() : "Illegal argument");
			throw new IllegalStateException(formatInvokeError(text, 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 {
				throw new IllegalStateException(formatInvokeError("Invocation failure", args), targetException);
			}
		}
	}

3.ServletInvocableHandlerMethod类详解

ServletInvocableHandlerMethod类继承了InvocableHandlerMethod类,新增了处理返回值HandlerMethodReturnValueHandler的能力,并且新增了调用控制器方法的回调方法;

回调invokeAndHandle方法源码如下:

	/**
	 * Invoke the method and handle the return value through one of the
	 * configured {@link HandlerMethodReturnValueHandler HandlerMethodReturnValueHandlers}.
	 * @param webRequest the current request
	 * @param mavContainer the ModelAndViewContainer for this request
	 * @param providedArgs "given" arguments matched by type (not resolved)
	 */
	public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
			Object... providedArgs) throws Exception {
		//调用父类InvocableHandlerMethod的回调方法,并返回调用接口控制器方法的返回结果
		Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
		setResponseStatus(webRequest);

		if (returnValue == null) {
			if (isRequestNotModified(webRequest) || getResponseStatus() != null || mavContainer.isRequestHandled()) {
				disableContentCachingIfNecessary(webRequest);
				mavContainer.setRequestHandled(true);
				return;
			}
		}
		else if (StringUtils.hasText(getResponseStatusReason())) {
			mavContainer.setRequestHandled(true);
			return;
		}

		mavContainer.setRequestHandled(false);
		Assert.state(this.returnValueHandlers != null, "No return value handlers");
		try {
      //将控制器返回的结果交给HandlerMethodReturnValueHandler来处理
			this.returnValueHandlers.handleReturnValue(
					returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
		}
		catch (Exception ex) {
			if (logger.isTraceEnabled()) {
				logger.trace(formatErrorForReturnValue(returnValue), ex);
			}
			throw ex;
		}
	}

4.ConcurrentResultHandlerMethod类详解

ConcurrentResultHandlerMethod是ServletInvocableHandlerMethod的一个内部类,也是它的子类,支持异常调用结果处理(暂时没有发现使用的场景)

到此这篇关于Spring中HandlerMethod类源码详细解析的文章就介绍到这了,更多相关HandlerMethod类源码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于Java实现回调监听工具类

    基于Java实现回调监听工具类

    这篇文章主要为大家详细介绍了如何基于Java实现一个回调监听工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-04-04
  • spring集成redis cluster详解

    spring集成redis cluster详解

    这篇文章主要介绍了spring集成redis cluster详解,分享了maven依赖,Spring配置,增加connect-redis.properties 配置文件等相关内容,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • springboot项目账户注册逻辑功能实现

    springboot项目账户注册逻辑功能实现

    这篇文章主要介绍了springboot项目账户注册逻辑功能实现,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2024-12-12
  • Spring Bean三种注入方式详解

    Spring Bean三种注入方式详解

    本篇文章主要介绍了Spring Bean三种注入方式详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • Java实现音频转码(WAV、MP3、AMR互转)

    Java实现音频转码(WAV、MP3、AMR互转)

    本文主要介绍了Java实现音频转码,包括WAV、MP3、AMR互转,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-02-02
  • java实现监控rtsp流转flv方法实例(前端播放,前后端代码都有)

    java实现监控rtsp流转flv方法实例(前端播放,前后端代码都有)

    这篇文章主要给大家介绍了关于java实现监控rtsp流转flv的相关资料,文中介绍的是前端播放,前后端代码都有,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-06-06
  • jwt生成token和token解析基础详解

    jwt生成token和token解析基础详解

    这篇文章主要为大家介绍了jwt生成token和token解析基础,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • Java 动态生成类和实例, 并注入方法操作示例

    Java 动态生成类和实例, 并注入方法操作示例

    这篇文章主要介绍了Java 动态生成类和实例, 并注入方法操作,结合实例形式分析了Java 动态生成类和实例以及动态注入相关操作技巧,需要的朋友可以参考下
    2020-02-02
  • SSH框架网上商城项目第17战之购物车基本功能

    SSH框架网上商城项目第17战之购物车基本功能

    这篇文章主要为大家详细介绍了SSH框架网上商城项目第17战之购物车基本功能的实现过程,感兴趣的小伙伴们可以参考一下
    2016-06-06
  • SpringBoot整合Ehcache3的实现步骤

    SpringBoot整合Ehcache3的实现步骤

    本文主要介绍了SpringBoot整合Ehcache3的实现步骤,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01

最新评论