HandlerMethod类源码解析

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

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

在这里插入图片描述

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

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

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

	/*** 获取request请求参数,调用控制器方法**/@Nullablepublic 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方法源码:

	/*** 使用给定的参数调用控制器方法**/@Nullableprotected 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的一个内部类,也是它的子类,支持异常调用结果处理(暂时没有发现使用的场景)

GitHub地址:https://github.com/mingyang66/spring-parent/tree/master/doc/base

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/1619725.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Spring MVC 学习总结

学习目标 了解 Spring MVC 是什么&#xff0c;为什么要使用它或者说它能解决什么问题&#xff0c;其与 Spring 是什么关系。理解为什么配置 Spring MVC 的前端控制器的映射路径为 “/” 会导致静态资源访问不了&#xff0c;掌握怎么处理这个问题。掌握基于注解方式使用 Spring…

java反射之Method的invoke方法实现

在框架中经常会会用到method.invoke()方法&#xff0c;用来执行某个的对象的目标方法。以前写代码用到反射时&#xff0c;总是获取先获取Method&#xff0c;然后传入对应的Class实例对象执行方法。然而前段时间研究invoke方法时&#xff0c;发现invoke方法居然包含多态的特性&a…

java method方法_java入门(六) | 方法(Method)的定义和使用

上一期是对java的分支结构进行讲解和实练,分支结构有if 、if(判断语句..){满足条件的代码...}else{不满足的代码}、else if以及switch case,你对他们有理解的怎样呢? 这一期是对方法method的介绍,它也被称之为函数,它的基本格式为: 方法的修饰符 方法的返回值 方法的名字…

Java中的方法(method)

1.方法概述 什么是方法&#xff1f; 方法是具有独立功能的代码块组织成为一个整体&#xff0c;使其具有特殊功能的代码集 注意&#xff1a; 方法必须先创建才可以使用&#xff0c;该过程称为方法定义 方法创建后并不是直接运行的&#xff0c;需要手动使用后执行&#xff0c;该过…

计算机组成原理(主存储器的基本组成、 运算器的基本组成、 控制器的基本组成、完成一条指令的三个阶段)

主存储器的基本组成&#xff1a; 这个是读数据操作图&#xff1a; 读入数据与菜鸟驿站的取货流程差不多&#xff1a; 写入数据的过程与读入数据类似&#xff1a; 1、cpu 指明想要写入到那个位置&#xff08;写到MAR中&#xff09; 2、想要写入的数据会放到MDR中 3、c…

MVSNet 代码注释版 下载 (pytorch版)(注释非常详细,较源码结构有调整,使用起来更方便)

MVSNet 代码注释版 下载 &#xff08;注释非常详细&#xff0c;代码结构有所调整&#xff0c;使用起来更方便&#xff09; 本代码不仅进行了详细注释&#xff0c;还对源码做了相应调整&#xff0c;可以更方便用户使用&#xff0c; 结构上&#xff0c;更加清晰&#xff1b; 代…

超级计算机运行吃鸡,决赛圈的时候,如果两个人同时被手雷炸死该怎么办呢?...

这款这么火的绝地求生&#xff0c;在决赛圈的时候如果真的两个人被手雷同时炸死该怎么办呢&#xff1f;小编就告诉你自己的亲身经历吧。 第一个&#xff1a;手雷在你手中爆炸&#xff0c;然后与敌人同归&#xff0c;相信大多数人有这样一种习惯&#xff0c;捏住手雷5秒扔掉&…

WebGL非矩阵变换

目录 平移 示例代码&#xff1a; 齐次坐标矢量的最后一个分量w 旋转 p的坐标&#xff0c;可得等式 R1&#xff1a; 使用r、α、β来表示点p的坐标&#xff0c;可得等式 R2&#xff1a; 利用三角函数两角和公式&#xff0c;可得等式 R3&#xff1a; 最后&#xff0c;将…

Unity中抛物线C#实现的两种方式

在游戏中会出现抛物线的方式&#xff08;如&#xff1a;炮弹轨迹&#xff0c;扔手雷等&#xff09; 下面是实现了两种方式&#xff0c;在学习之路上不停探索。欢迎指出不足&#xff0c;共同进步 实现— 根据开始位置跟结束位置做抛物线 using UnityEngine; using System.Col…

iPhone游戏 Fragger 扔手雷 通关

这个小游戏我觉得根愤怒的小鸟有的一拼,而且它的操作方式又很类似早期的PC网络游戏疯狂坦克. 我在疯狂坦克中的排名是1000以内,所以我是金牌,玩这个游戏又找到了当年的感觉. 以图片记录一该游戏中的关卡,个人觉得它们都是不错的设计.

Unity实用案例之——“吃鸡”手雷弹道模拟

最近吃鸡游戏火啊&#xff0c;至今也吃了好几晚的鸡了&#xff0c;无奈手雷就是丢不准&#xff0c;从窗户丢雷丢几个弹出几个&#xff0c;各种误伤自己人……而别人家的手雷&#xff1a; 一般的游戏里手雷都是盲投&#xff0c;不过一般游戏也不会对弹道有这么精确的要求&…

Unity3D——射击游戏(多地图,多人物,枪支切换,驾车,扔手雷等功能,堪比小型和平精英)

演示1: 演示2: 演示3: 演示4&#xff1a; 源代码和运行程序 链接&#xff1a;https://pan.baidu.com/s/1QZ9UGWPAHO1zRgW5qNCjcw?pwd4m31 提取码&#xff1a;4m31 本款游戏是一个多场景&#xff0c;多角色&#xff0c;多枪支可选的枪战游戏&#xff0c;类似于市面上的小型…

C# textBox1.Text=““与textBox1.Clear()的区别

一、区别 textbox.Text "" 和 textbox.Clear() 都可以用于清空文本框的内容&#xff0c;但它们之间有一些细微的区别。 textbox.Text "": 这种方式会将文本框的 Text 属性直接设置为空字符串。这样会立即清除文本框的内容&#xff0c;并将文本框显示为空…

几个nlp的小任务(生成任务(摘要生成))

几个nlp的小任务生成任务——摘要生成 安装库选择模型加载数据集展示数据集数据预处理 tokenizer注意特殊的 token处理组成预处理函数调用map,对数据集进行预处理微调模型,设置参数设置数据收集器,将处理好的数据喂给模型封装测评方法将参数传给 trainer,开始训练安装库 选…

Vue3(开发h5适配)

在开发移动端的时候需要适配各种机型&#xff0c;有大的&#xff0c;有小的&#xff0c;我们需要一套代码&#xff0c;在不同的分辨率适应各种机型。 因此我们需要设置meta标签 <meta name"viewport" content"widthdevice-width, initial-scale1.0">…

JDK介绍

JDK,JRE和JVM之间的关系 JVM是运行环境&#xff0c;JRE是含运行环境和相关的类库&#xff0c;跟node环境是一个意思 JDK目录介绍 目录名称说明bin该路径下存放了JDK的各种工具命令。javac和java就放在这个目录。conf该路径下存放了JDK的相关配置文件include该路径下存放了一些…

【算法训练-链表】合并两个有序链表、合并K个有序链表

废话不多说&#xff0c;喊一句号子鼓励自己&#xff1a;程序员永不失业&#xff0c;程序员走向架构&#xff01;首先&#xff0c;链表对应的数据结构在这篇Blog中&#xff1a;【基本数据结构 一】线性数据结构&#xff1a;链表&#xff0c;基于对基础知识的理解来进行题目解答。…

alias命令手册

alias&#xff1a;查看和定义别名 功能描述 alias命令用来设置指令的别名。使用alias时&#xff0c;用户可以使用单引号 ‘ ‘ 将原来的命令引起来&#xff0c;防止特殊字符导致错误。 alias命令的作用只局限于该次登入的操作。若要每次登入都能够使用这些命令别名&#xff0c;…

Ubuntu学习之alias命令

Ubuntu学习之alias命令 1.1 alias功能介绍 当我们经常需要在命令窗键入复杂冗长的命令时&#xff0c;alias就派上用场啦。alias允许用户为命令创建简单的名称或缩写&#xff0c;哪怕这个缩写只有一个字符。即为指令设置别名。 1.2 alias语法 语法&#xff1a;alias [name”va…