SpringBoot:参数处理原理图解 ---- 8.2

sss读前必看:通过Web开发相关原理那篇文章我们知道,请求映射原理是:DispatcherServlet调用父类中的doGet和doPost,而这两个方法的核心方法是processRequest(request, response) ,而这个方法的核心方法是一个抽象方法doService(request, response),并未做具体实现,而DispatcherServlet实现了这个方法,并且其中最核心的方法是 doDispatch(request, response),因此我们通过deBug方式在doDispatch处打断点学习具体的参数处理是如何工作的。(我们调用的是getCar()方法相应的请求)
在这里插入图片描述
在这里插入图片描述

参数处理原理

①、请求DispatcherServlet

sss1 打断点:DispatcherServlet ==> doDispatch()
在这里插入图片描述

②③、通过请求返回处理器执行链

sss2 HandlerMapping - 找到能处理请求的处理器执行链,也就是HandlerExecutionChain(对应相应的Controller.method())

sdsss【注1】:怎么找呢?通过处理器映射器HandlerMapping进行寻找,而我们一共有五个处理器映射器放在HandlerMappings中,所以通过迭代器(老版本用的for循环)寻找哪个处理器映射器中对有相应的处理器执行链HandlerExecutionChain,然后返回相应的处理器执行链。(处理器映射器5个)
在这里插入图片描述
在这里插入图片描述
sdsss【注2】:RequestMappingHandlerMapping:保存了所有@RequestMapping 和handler的映射规则。 所有的请求映射都在HandlerMapping中。(比如下图中,这个处理器映射器就存储了所有的我们建立的controller包下的类中的@RequestMapping 相关方法)
在这里插入图片描述
sdsss1. SpringBoot自动配置欢迎页的 WelcomePageHandlerMapping 。访问 /能访问到index.html;

sdsss2. SpringBoot自动配置了默认 的 RequestMappingHandlerMapping

sdsss3. 请求进来,挨个尝试所有的HandlerMapping看是否有请求信息。
sdsdsdsss• 如果有就找到这个请求对应的handler
sddsdssss• 如果没有就是下一个 HandlerMapping

sdsss4. 我们需要一些自定义的映射处理,我们也可以自己给容器中放HandlerMapping。自定义HandlerMapping

sdsss到此我们可以发现,通过 mappedHandler = this.getHandler(processedRequest) 我们可以得到对应的处理器执行链HandlerExecutionChain,也就是找到了相应的Controller.method(),即getCar()方法。
在这里插入图片描述

④、 HandlerAdapter - 为当前的 Handler (这个Handler目前还在处理器执行链中) 找一个对应的适配器

在这里插入图片描述
sssgetHandlerAdapter(Object handler)并解析第一行代码,发现一共有四个适配器,然后通过迭代器判断当前四种 HandlerAdapter 中哪一种支持当前 handler:

在这里插入图片描述
sdsss[注1]:0 - 支持方法上标注@RequestMapping 1 - 支持函数式编程…

sdsss到此我们可以发现,通过 HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());我们可以得到对应的适配器:RequestMappingHandlerAdapter
在这里插入图片描述

⑤⑥⑦、 适配器执行目标方法并确定方法参数的每一个值

sss利用找到的 适配器HandlerAdapter 真正对处理器handler进行操作,并返回相应的ModelAndView
在这里插入图片描述
sss mv = ha.handle(processedRequest, response, mappedHandler.getHandler()):(mv就是返回的ModelAndView)
在这里插入图片描述
sss 点击进入该方法(核心是handleInternal):
在这里插入图片描述
sss 总之:最终的执行在 RequestMappingHandlerAdapter 中的 handleInternal()方法,执行返回 ModelAndView:

ssss接下来我们重点分析: mav = this.invokeHandlerMethod(request, response, handlerMethod):其中主要的方法有四个(3个也行) :(还有一点就是当下图中的③执行完后,其实我们已经处理好了方法,已经可以通过浏览器看到结果,后续的④就是关于一些ModelAndView的,在没有转发或者一些其他的参数下基本是用不到的,具体应用下篇文章《SpringBoot:参数处理原理 (复杂参数)---- 8.3》)会分析到。
在这里插入图片描述

①、argumentResolvers 参数解析器 ②、returnValueHandlers 返回值处理器:

sss方法 ① :invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);

sss方法 ② :invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
在这里插入图片描述
sss方法源码:

public void setHandlerMethodArgumentResolvers(HandlerMethodArgumentResolverComposite argumentResolvers) {
    this.resolvers = argumentResolvers;
}
public void setHandlerMethodReturnValueHandlers(HandlerMethodReturnValueHandlerComposite returnValueHandlers) {
    this.returnValueHandlers = returnValueHandlers;
}

sss【注 1】:
sdasdassdasdasdasddsa在这里插入图片描述
sss【注 2】:
sdasdassdasdasdasddsa在这里插入图片描述

③、执行目标方法:(重点!!!)

sssinvocableMethod.invokeAndHandle (webRequest, mavContainer, new Object[0]); (mavContainer是Model 和 View 的容器)

sss方法源码:
在这里插入图片描述
sss获取request中执行方法相应的参数值(复杂),也就是invokeForRequest()方法:
在这里插入图片描述
sss【注】:doInvoke(args)就是利用反射执行方法体,因为此时方法名,参数都已经知道了,就剩下方法体的执行,和返回值的处理了。
sss【注】:怎么获取执行方法的所有对应的参数值呢?通过getMethodArgumentValues(request, mavContainer, providedArgs)方法获得:
在这里插入图片描述

③/1、获取方法参数的第一步:先得到所有参数对应的注解以及参数类型

在这里插入图片描述

③/2、获取方法参数的第二步:根据每个参数的注解和类型获取解析器(这里是通过迭代找出可以解析参数注解的解析器,然后将他们放入到缓存中,方便读取),然后利用获得的参数解析器解析得到参数值

在这里插入图片描述
sss在这里插入图片描述
sss【注1】:进入supportsParameter(MethodParameter parameter)发现核心方法是getArgumentResolver(parameter),源码:
在这里插入图片描述
在这里插入图片描述
sss到此,【注1】就完成了,接下来就是利用解析器获取参数值:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
sss到此:参数就完成了绑定,然后通过循环,就给每个参数都获取了值。然后再执行完doInvoke()方法,整个核心方法就完成了。
总之就是:遍历每个参数,找到参数解析器解析参数。下面再看一下其中的细节:
在这里插入图片描述
在这里插入图片描述

③/4、到此invokeHandlerMethod中的三个方法就执行完了,然后通过getModelAndView()方法 返回mv就好了。
⑧、ModelAndView返回后,后续的内容就先不更新啦,关于获得mv的后续内容,下一篇文章8.3讲解

在这里插入图片描述
在这里插入图片描述

其他参数的相关原理:

Servlet API

sssWebRequest、ServletRequest、MultipartRequest、 HttpSession、javax.servlet.http.PushBuilder、Principal、InputStream、Reader、HttpMethod、Locale、TimeZone、ZoneId

sss原理同上 ,只不过参数解析器适配请等不同而已,ServletRequestMethodArgumentResolver 能解析以上部分参数,如下:

@Override
	public boolean supportsParameter(MethodParameter parameter) {
		Class<?> paramType = parameter.getParameterType();
		return (WebRequest.class.isAssignableFrom(paramType) ||
				ServletRequest.class.isAssignableFrom(paramType) ||
				MultipartRequest.class.isAssignableFrom(paramType) ||
				HttpSession.class.isAssignableFrom(paramType) ||
				(pushBuilder != null && pushBuilder.isAssignableFrom(paramType)) ||
				Principal.class.isAssignableFrom(paramType) ||
				InputStream.class.isAssignableFrom(paramType) ||
				Reader.class.isAssignableFrom(paramType) ||
				HttpMethod.class == paramType ||
				Locale.class == paramType ||
				TimeZone.class == paramType ||
				ZoneId.class == paramType);
	}
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
《算法图-python.pdf》是一本介绍算法和使用Python语言实现算法的书籍。该书的目的是帮助读者了算法的基本概念和原理,并通过Python编程实践来加深理。 这本书以图的方式呈现算法的思想和应用,使复杂的算法问题变得直观易懂。读者可以通过阅读该书,学习到各种常见的算法设计和决思路,如排序算法、搜索算法、图算法等。同时,该书也会介绍一些高级算法,如动态规划、贪婪算法等,以及如何通过Python语言实现这些算法。 《算法图-python.pdf》的内容结构清晰,通俗易懂。每个算法都有详细的释和示例代码,读者可以通过实际编程来加深对算法的理。此外,书中还包含了一些挑战性的练习题,供读者进一步巩固所学的知识。 通过阅读《算法图-python.pdf》,读者不仅可以学习到算法的基本知识,还可以了到如何运用Python语言实现这些算法。这对于刚开始学习算法和Python编程的读者来说是非常有帮助的。无论是计算机科学专业的学生,还是对算法感兴趣的爱好者,都可以从这本书中受益匪浅。 总之,《算法图-python.pdf》是一本很好的算法入门书籍,以图和Python编程为特色,适合各类读者学习和参考。通过阅读和实践,读者可以提高算法设计和编程实现的能力,为决实际问题提供有效的思路和方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值