00:00
好,前面呢,我们测试了一下spring mvc底层常用的一些注解,那也很神奇,我们只需要呢,给方法参数位置来标注这些注解,Spring mvc就会按照你的要求自动的在我们这个调用目标方法的时候,帮这些参数确定好值,你在下边就可以使用了,但是它整个自动确定值的过程,以及它的源码是怎么写的,我们也可以来进去看一下,好,我们大概来进来,我们所有的这个源码呢,我们肯定是从dispaure so light开始,因为这是来处理请求的整个入口disppaure so里边我们的do dispatch方法来打个断点,我们来以debug方式来运行,我们来看一下我们的整个这一块,它是怎么解析出每一个参数的值是多少。里边呢,也会牵扯到spring m VC里边的一些核心组件,好,那现在来测试一下,首先我来翻我们的这个请求,叫卡三欧尔李四我们的这个请求,因为我们是来处理卡3OWNER张三之类的这个请求,来发送这个请求,Debug呢来到我们的dotypa方法,那前置的这个流程呢,我们大概过一下这来检查是否文件上传请求,而这一块呢,大家都知道,这呢是我们通过handler mapping里边找我们哪个handleler能处理请求,可以大概step into进来一下,我们的handler mapping有很多我们主要标了request mapping还这个注解的,所以呢,在它的整个映射这个中心里边,由我们这个映射关系,我们当前的这个请求是交由谁处理的,所以相当于通过这来遍利所有的handle德ler mapping能找到我们当前哪个handleler处理请求的,所谓的这个handleler就是封装了我们的这个目标方法的这些整个信息,好,然后呢,接下来我们继续。
01:44
往下走,加最关键的一步在这,然后呢叫handler adapter for the current request决定一个handler的这个适配器和处理器,适配器为当前请求,我们现在呢,已经知道我们在上一步呢,已经找到我们哪个方法能处理这个请求了,我们把这个方法呢可以拿到。
02:05
大家看我们呢,是这个叫permeer,我们的test controller的get car这个方法,包括完整签名在这都有,然后呢,我们已经知道这个方法能处理请求了,但是呢,后来u OA spring mvc要在底层利用反射调用这个方法,而且呢要确定一大堆这些方法每一个参数的值,所以这其实是一个很麻烦的过程,所么MVC呢,就把这个麻烦的过程封装到了我们的这个handler adapter里边,相当于这就是一个大的这个反射工具,然后呢,先为当前这个handleler找到我们的这个handler adapter,先找到我们的这个适配器,未来呢会用这个适配器,我们来看适配器,最终调用handle,然后呢处理我们的这个目标方法,所以这是spring m VC里边的一个设计思想,好,我们整个原理呢是这样,首先呢,从handler mapping里边,Mapping中找到能处理请求的handler,也所谓的handler,就是我们说的能处理请求的controller的哪个方法?
03:06
的哪个方法,他把这些详细信息呢,封装到了handle到了里边,然后呢,为当前handle了,为当前handle了,为我们找到的这个的这个,然后呢,再来找一个适配器,适配器所谓的这个适配器呢,我们。这个适配器我们可以来看一下handle了,Adapter它呢其实是一个spring m VC底层设计的一个接口,这个接口呢有这么几个方法,第一个suppose,虽然我支持处理哪个哪种看到了,然后呢还有加,如果我支持的话,就调用真正的这个方法来处理,哎,试下这个我们就不用管了,所以呢,这是一个接口的这个设计,我们未来呢也可以自定义handleler adapter来处理一些复杂的东西,我只要告诉spring mvc,我自定义的这个handleler adapt支持处理啊,哪种handle到了,相当于哪个controlrler的哪个方法,如果这个controlrler这个方法啊,我能支持,那最终呢,就会调用我自定义的这个handle动方法来进行处理,那我们未来原码里边也能看到这个过程,所以呢,他先来找到了这个adapter,那怎么找的也,我们也可以debug进来看一下,好,先找到原生的这个handle了啊,我们封装了这个方法没问题,我们再来step into才能进这个方法,Step into它呢相当于在所有的handler adapts里边来去确定所有的handler adapter有。
04:29
我们这四种,这四种呢,最终给我们解释的这个意思就是好,我们来把我们的关键的这几点我们都放过来,第一个第一个是我们的这个handleler和adapter,我们的这个处理器的适配器,处理器的适配器呢,默认现在四种,这四种呢,其实未来就是完成不同的功能的。哪个不同的功能呢?首先第一个handle adapter,第一个第一个呢就是支持,支持我们标注request maping,支持方法上标注at request mapping在注解的,然后呢,它的这个适配器,第二种呢,Handle了function,你一听这个function其实呢,它是来支持我们函数式,函数式编程的,也就是说你未来呢,你可以给你的容器中放一个controlrler,那这个controlrler呢,声明了一大堆是函数式方法,而不是我们这个普通方法,所以呢,函数式方法呢,人家就用函数式的这个adapter,当然还有其他的各种adapter来简单的adapter等一大堆,那我们这两种呢,用的是最多的,那我们现在。
05:44
能找到的是哪个adapter呢?我们默认写的这些CTRL了都找到,是第一个requesting看到了adapter。我们可以来家给大家看一下,我在这来挨个匹配来找他,先来判断我们当前adapter支不支持当前handleler,怎么判断支持呢?因为我们这个当前handler它被封装成了一个handler method,我来step into,进来,我们的这个step into,我再来进来,进来我们来确认一下啊,这个判断呢,非常方便,只要你的这个handleler是我们的handler man速类型,那巧了,我们。
06:18
当前正式把这个憨到了,来看一下啊,我这个憨到了,哎。让他执行一下,我们正式把我们封装了这个方法的这个handle德了,我们封装成了也handle德拉的,所以呢,它的这个判断会生效,哎,它就是这它旗下的,所以呢我就支持,相当于最终呢会给我们返回第一个我们遍利的adapter,就是这个request monkey,看到了adapter request mention handler adapt好control后我们把它拿到。所以呢,这个adapt是我们会默认得到的,当然大家呢,一开始听这些名字都先混一个耳耳熟就行了,好先为我们当前请求找到了一个这个适配器,找到适配器以后,我们来看他怎么做啊,我们就让他把这个适配器返回,找到适配器以后呢,他判断我们当前请求是不是get方法,而且呢,如是不是headd headde呢,相当于不是我们处理,呃,服务器真正处理的,它相当于是一个打头屏啊,如果有浏览器缓存还来进行缓存的,好,我们这一块过去后呢,这一块我们不用管,然后关键核心就在这invos handler,然我们一听这句话呢,翻译过来就叫真正的执行handler,它呢是利用我们的这个handler adapter,也就是我们刚才找的这个适配器,然后把我们的目标handler、目标方法以及request response全部传进去,帮来执行目标方法。
07:43
所以呢,核心关键点又在这,呃,接下来第二大核心关键点叫执行目标方法,执行目标方法呢,是我们dispaure so late类里面do dispatch里边的这个方法,然后呢,这个方法的详细内容,好,我们这个方法呢,我们得标注一下,大家得知道这是我们的dispaure sol。
08:08
这个类里边的do dispach方法里边的这一行,然后呢,这是执行目标方法,好来到这,来到这以后我们来看它怎么执行目标方法step into,先得到我们的目标handle了,没问题,相当于我们将会那个请求将会调用我们这个类的这个方法来处理,包括方法的整个参数签名我们都能得到,然后呢,接下来我们再来step into才能进入到啊handle adapter的handle方法step into好进来以后呢,它在这handle internal好,我们来进入内部的处理细节,内部处理细节呢就来到了requestping handle了,想对于我们目标方法的真正执行都在request看到了里边,然后最终执行完以后呢,我们整个方法会返回model and view后来再说,然后我们来下一步进行放行,然后呢,接下来我们关注一个最大的这一点,叫invoke handler method,相当于我们要翻译过来,就叫执行handler的方法。
09:08
嗯。然后呢,我们把这一句话拿来放在这儿,怎么执行目标方法,它是在这个类里边。调用了这么一句话,这个呢是来执行我们目标方法。执行目标方法,因为老师按照翻译呢,直接就给大家说了,我们也不用,哎先放行,再看一下目标方案有没有执行,没有必要那样一一确定好,这样呢是我们执行目标方法,我可以再次step into进来,我看目标方法咋执行,前面大家能看到的整个new过程都是一些初始化过程,但是呢,我来看这些过程的时候,我得到了几个关键字,第一个关键字叫argument reserve,哎,我们一翻译呢,这叫参数解析器。所以我们来看一下核心参数解析器。参数解析器呢,有26个。
10:00
所以这接下来就是一个核心,我们在目标方法还没执行前,我们看到了它会为一个叫invo able method的可执行的方法里边设置参数解析器,所谓的可执行的方法其实就是我们这个目标方法,它又呢封装了一层,所以呢,接下来我们的一个核心关键。执行目标方法的核心关键,我们呢会设置参数解析器,这个参数解析器呢有26个。也这样,其实就是说明了我们将来目标方法的每一个参数值是什么,是用这个参数解析器确定的,所以它的这个作用就是来确定我们将要执行的。目标方法的每一个参数的值是什么?所以呢,这26个参数解析器,我其实按照名字我大概就能知道,然后呢,叫request power method的argument reserver,反正他们都叫的argument reserve,就是呢方法参数解析器,第一个呢是来解析request p的,相当于你的这个方法,你的目标方法如果标注了request p这个注解,我就用这个解析器给你解析,然后呢,第二个。
11:15
叫pass variable,如果你的这个目标方法标注了pass variable这个注解,我呢就用这个参数解析去解析,一句话就是说我们spring mvc到底我们的这个目标方法位置能支持写多少种参数,我们是要看这些参数解析器能解析哪些,所以呢,我们这个spring MC,咱们这个目标方法能写多少种参数类型,然后呢,取决于取决。与我们这个参数解析器参数解析器,而且这个参数解析器呢,我们可以来给大家看一下啊,这个参数解析器,参数解析器它在这设计点进来,这个参数解析器呢,它是一个接口,所以呢,参数解析器的这两个接口我来CTRL f12大家拿过来,大家就会发现这个接口设计的呢也很有意思。
12:13
他呢,是这么来设计我们这个参数解析器的接口的。就是说首先我们的接口的第一个方法叫support p,我们当前是不是支持这种参数,如果支持的话就调用resolve来进行解析,所以这参数解析器就是啊,如果他要工作,那就是两步,第一步先来判断当前参数支不支持解析。当前解析器支持哪种参数解析,他要判断当前解析器当前我们一会儿在源码里边也能看到这个过程,当前解析器支持解析。哪种参数,然后呢,接下来如果我支持解析是应该是是否支持解析这种参数,因为我呢会给你传一个参数的详细信息,然后呢,如果支持支持就调用解析方法,就调用resolve的这个argument方法来进行解析,不支持就算了,大家看啊,我给你传一个参数,如果你支持给我返回处支持了,就调用它来解析,那我们来看一下源码里边是怎么写他的这个行为的,然后我们现在呢懂了,我们所有的这个参数类型是利用参数解析器最终来解析的。另外与此同时我们也看到了一个叫return value6看到了叫返回值处理器,也就是说我们的这个目标方法到底能写多少种类型的返回值,也取决于我们这些返回值处理器,它能支持什么返回值?处理器有15种,那大概我就懂了,我们的这个方法位置能写哪些呢?
13:54
我们方法的返回值能写model and view,如果用过spring MC的都知道,我们返回值也能写model,我们返回值也能写view,我们返回值还能标response body,反正等等一大堆,我们返回值还能写HVNTT,一大堆的东西,这就是相当于我们看它我们就知道了,哎,我们返回值又能干哪些活?好,我们在这儿再来一个,人家呢还有一个叫返回值解析器,123叫返回值处理器,哎,参数呢是解析器,返回值呢,人家叫处理器,好我们把这个呢拿过来,这个起名呢,如果你要深究,还是非常有细节的,好,我们一会儿来看一下啊,现在呢,我们知道了一个参数解析器,还有一个返回值处理器,我们来看他们是怎么工作的,他们呢?
14:46
提前spring m VC提前把这些呃,返回值处理器,参数解析器都放到了这个目标方法包装的叫solid invo,我们这个solid可执行的这个处理器方法里边,这有返回值处理器在这保存了15个,这有我们的参数解析器RS在这呢保存了26个,然后呢,接下来我们其他的我就不关注,我给大家把这些非核心的我都直接给大家跳过来,到我们核心这一步,叫invo Apple method invo and handle叫执行并处理。所以呢,真正五来执行目标方法,那就来这儿了,因为invo able method,这就是我们的目标方法,目标方法里边所有的东西已经封装完了,包括这些处理器也都已经在了,然后接下来我们来看它怎么办,Step into进来,进来以后呢,接下来它在这开始要执行了,而且一执行大家来看第一个方法叫in work for request,现在执行当前请求,如果我把这个方法已放行,它呢,就自然会来到。
15:46
我们的这个目标方法。因为我们按照这个方法名,我一听就叫in work for request啊,执行我们这个请求,然后完了以后呢,会有一个返回值,所以我给这打两个断点,大家看啊,如果我把这个断点一放行,他是先来到下边断点呢,还是先来到我的这个controller,如果先来到我的controller,说明我的这个断点一放行,就是真正来执行目标方法,好,我来放行,走诶我们发现来到ctrler了,我再放行才来到下一个,所以呢,真正执行目标方法在这。
16:19
那这块的源代码呢,我们也放在这个位置,真正执行目标方法,真正执行目标方法的这个方法呢,是在我们的这个类里边。大家如果想来看的话。在这好,然后呢,他要真正执行目标方法,真正执行目标方法就包括什么,包括呢,我们要确定目标方法里边每一个参数的这个值是多少,所以我们来看它怎么真正执行目标方法的,我们把这些全部放行请求再来一遍走。好,我来放行,放行,放行到我们真正执行目标方法在这儿,我来step into,走起走进来,然后呢,大家看第一步。
17:02
第一步叫get method的argument values,第一步先获取方法的所有参数的值,如果我把这一步一放行,大家看这个as相当于我方法的十个参数的这些值,大家看这都已经准备好了,第一个参数值是三,第二个是李四,第三个呢是ID3USER内姆李四,这值人家都已经确定好了,所以呢,确定方法参数值在这儿,然后呢,你确定好参数值以后呢,Doing work,这肯定就是利用反射调用我们目标方法,大家看这都开始进入到反射工具类了,所以我就不用看了,我直接放行,我重新再来一次,我们来看他怎么确定才入职的。来刷新。好,我来放行,放行,然后呢,来到我们这一块,获取我们这个方法参数值。还在爆哀报,看到了man速这个里边。还在这儿,所以呢,这是它的内部的第二步获取方法,参数值,参数值它是怎么获取的,大概一看就行了,来,Step into直接进来,然后呢,核心就在这儿了。
18:14
把这个这一段话搞清楚,我们方获取方法参数值是怎么获取的,大家就清楚了,然后呢,这一步才是真正的如何确定目标方法,每一个参数的值如何确定呢?我把这段Java代码放在这,这段Java代码的出处在我们的in work handle里边。我们不妨来给大家看一下,在这个里边。好,我们来看一下它是怎么处理的。这一块呢,代码也写的非常清楚,首先get method的permit,先获取到我们方法所有的参数声明,相当于呢,第零个参数,第零个参数它标了什么注解,这都有,它标了pass variable注解,然后呢,这个参数的所引位置是什么,这个参数的类型是什么,相当于呢,它先获取到我们方法上所有参数的详细信息,现在还没确定值,比如第三个参数,它标的是我们的这个pass variable出现,再来看一下其他,比如我们第六个参数,它呃,第七个参数,第六第七个参数它标的呢是request per注解,像每一个参数它的这个类型又是什么,每一个参数的详细信息我们都获取到了,都获取到以后呢,它会先判断我们这个参数是不是为空,如果为空,因为我们这个目标方法没有参数列表,那我们自然而然无需确定任何值直接返回,但如果有参数列表,大家注意,咱拗了一个object,我们参数呢,有多少个,这个object数组就有多长,然后呢,最终这个X。
19:51
在这返回,也就是说我们返回的这个X,因为我们是step into进来的,所以呢,我们这个X呢,我们刚才放行,这是所有目标方法确定好的值,所以呢,最终相当于方法内部返回的这个R,那就是我们确定好的值,所以在中途它就已经把值确定好了,怎么确定好了,大家来看啊,我们先来声明了,2S,咱们十个相当于空object,这十个里边都是空的,因为我们有十个参数,接下来呢,我们来遍历,大家看parameters,我们有十个参数,按照长度挨个变历,先拿到第一个参数permeter I,如果我们的挨个变历I现在是零的情况下,I是零,拿到perter I相当于第零个参数,第零个参数呢,相当于我是参数列表里边的它in ID标了pass variable的来看,它是怎么办,拿到第零个参数以后呢,好,我们来确定一下,它确实呢是我们的这个integer类型,我们标注了passl variable这个注解的好,然后呢,接。
20:51
来,他在这什么引,这些引匿我们就不用管了。初始化的这些过程,然后呢,它都是来找一些什么叫参数的名字的,这些发现器相当于来确定参数的名字,好大家接下来注意啊,X。
21:07
接下来呢,它准备给二个I赋值,这个值怎么赋好的呢?我们不用管,因为真正的核心在这,我们能看到呢,这一块有一个叫this resolves reserve argument,然后呢,我们第一步现在是2G0,大家看啊,2G0现在给的值是一个梦,因为我们现在要确定二个零的值,二个零的值在下边,只有我们解析器解析了才有,所以解析之前它会在这判断this reserve supports p,先判断我们当前解析器是不是支持我们这种参数类型,好,我给这打一个断点,而且呢,我把这个停掉,我重新debug起来,我们来看它第一次运行的情况下,他怎么知道我们参数解析器支不支持这种参数类型。来确定一下啊,我来重新发送我们这个请求,回车来到这,我们来确要确定目标方法的参数值了,走走好,我们来判断P,这是我们的第一个参数,第一个参数呢,是来标了我们pass variableable注解的这个参数没问题,它要进来呢,先到reserves,我们26个receivevo参数解析器,参数解析器呢,它要判断我们这26个参数解析器支不支持我们这个参数,它怎么判断的step into进来,然后呢,接下来再来step into。
22:30
再来step into,它呢是get这个再来step into进入到我们这个方法,它是怎么判断的?首先呢,这有一个什么argument reserve catch,这个catch呢是空的SIZE0,所以呢它先获取一个result result呢现在是空的,也是空的呢就进来,进来呢大家会发现这是一个增强for循环便利这26个参数解析器,所以呢,它相当于是挨个确定我们这26个参数解析器谁能支持这种参数,哪种参数呢?P传进来就是这种。
23:03
我们第一个参数的详细信息全传了,标了这个注解的,它是在第一个索引,而这个参数的这个,呃,标的是这个,这个注解参数类型是什么,这个类型怎么感觉好像给丢了,包括utable啊,这个方法签名等等,反正这块的详细信息呢,在这都有,所以呢,我把这一段代码核心拿过来。他是来确定我们是不是能支持的。确定目标方法的每一个参数值,它是怎么确定呢?首先它是在这儿,我们来到它的这个细节里边。12345.1,先挨个判断,挨个判断所有参数解析器哪个支持解析这个参数,诶因为我们现在是确定第一个参数的值M,我们增加for循环,刚才是来到这个里边,然后它里边的详细内容在这儿。
24:01
它里边的详细代码实现在这儿,所以呢,它是怎么判断的,那么就来挨个编辑,先来看第一个参数解析器,第一个参数解析器叫request power method,我们来看它支不支持step into,进去看一下就知道了,它支不支持很简单,它的判断方法就是你给我传来的这个参数有没有has per notation,那有没有标注request power注解,巧了,我们没标,我们标的是pass variable注解,所以呢,第一个肯定判断失败。走,我们来进来,所以它在这呢,直接会return for,因为我们没有标这个注解,好我们在这儿大家看到return for相当于呢,我们第一个参数解析器就不支持,不支持呢,继续来遍历第二个参数解析器,我们来看第二个呢叫request map,第一个呢叫request,也就是说呢,你标了request permit,但是不封装map,第二个呢是封装map,来看它支不支持step into,它这个支持判断呢也很简单,第一个呢,就是判断我们当前传过来的这个参数,它呢是不是标了request。
25:06
P的这个注解我们来看,我们没标这个注解,所以我们没标呢,自然这一块不等于空就判断失败了,判断失败我们相当于就不支持,如果说我们标了的话,它还判断我们这个参数类型是不是map类型,如果是map类型它就支持,所以呢,我们现在参数类型不是map也没标,所以第二个不行返回,然后呢,接下来来到第三个,第三个呢,变成pass variable,我们的method argument server,它支不支持呢?Step into进来,然后呢,它是来判断我们的这个参数,我们这个参数是不是标了这个pass variable这个注解,Has per a notation,如果标了,哎,我们现在是标了是处非处就是false,如果你没标才会返回false,我们写的是标了啊,那标了以后呢,它再来判断我们的这个参数呀,它是不是map类型的。
26:00
那我们不是map类型的,如果是map类型的,它在这儿还要做一些事儿,我们这个参数呢,第一个参数应该就是一个很普通的,哎,很普通的不是map类型,所以呢,我们第一个应该放过,然后相当于我们的这个pass variable method argument reserve,它就支持解析,所以呢,我们通过这个一确定以后,我们相当于知道了,诶我们当前这个recover支持解析,那既然它支持了,就把它放到缓存里边,方便我们以后直接拿,要不然我们以后每次都要逐行逐逐个26个挨个确定谁支持谁不支持,很麻烦。所以呢,Spring Mac就是第一次你运行起来可可能很慢,只要一个请求执行过以后,整个spring m VC本地把好多组件全部缓存起来以后,我们就会越来越快,这也是它的缓存机制,好,那么现在呢,整过来以后,相当于我们终于找到了一个叫pass variable method的argument reserver,它支持解析我们第一个参数。那既然它。
27:00
它支持了,那么接下来我们就来解析,接下来resources.resolve所以我们的第一步就是判断是谁支持解析这个参数,现在我们判断成功了,接下来我们就进入到解析流程,5.2,解析这个参数的值。怎么解析这个参数的值呢?走。我们可以来确定一下step into进来,它呢拿到所有的这个参数解析器,对吧?我们拿到所有的参数解析器,我们就不用管了,他拿到相当于当前参数的这个参数解析器,因为我们在上一步判断的时候呢,我们已经知道它能解析了,他在这里边拿呢,我们之前而且有缓存了,所以他在这第一次拿肯定从缓存里面拿很快,然后呢,拿到我们能支持解析第一个参数的这个参数解析器,然后调用参数解析器的resolve方法进行解析就行了。step into它怎么解析的,那就过来,首先第一个叫name的什么value,我们来过来把参数的这个详细信息以参数的名字来看一下啊,参数的名字叫什么?这个name的info,我们这个参数的名字叫ID,没问题,在这参数的名字叫ID,然后呢,接下来在这就来解析我们这个参数的值了,叫reserve string value,先来解析解析谁呢?解析我们这个参数的值。
28:27
叫ID的这个值怎么解析,我来step into进来大家看一下就行了,Step into那怎么解析呢?接下来它就是用各种的我们这个解析器,诶我们刚才给放行了,也就是说用我们的这种各种的解析器,什么plus hold啦,Expression啦这解析器,然后拿解析器来进行计算,所以呢,我们的pass variable,它实际上就是。接接下来我们已经拿到passw这个参数解析器了,参数解析器呢,就相当于从我们整个路径里边,帮我们按照正则匹配的方式,最终解析到我们这个ID的值,这个值呢,我们来看到它现在解析,哎现在只是解析名啊,方法名的这个ID,现在我们现在要确定ID的值,ID的值是多少呢?那就在下边,哎最终在这呢,确定值怎么确定step into。
29:20
进来先step into会来到它string to string,我们先不用管好,我们现在进来,进来怎么办呢?进来就在这一步,叫URL temp这个VAR,来看一下这个temp VAR,这是什么东西,这个东西呢,其实是我们,我们把它这个展开。我们看到这有个ID3USERNAME,李四这一块的数据是从哪来的,这是我们之前大家还记得有没有一个叫URL pass helper这个helper呢?请求一进来会帮我们先把我们整个URL地址里边的啊,所有的这个路径变量全部呢解析出来,解析出来呢,人家提前还给你保存到request请求域中,所以我们接下来这个参数解析器超方便,直接在我们的这个请求域中拿到它的值就行了,所以呢,我们来看啊,请求域中呢,因为这个里边现在封装了我们所有这个路径变量的值,所以呢,接下来它只想要拿谁的值,只想拿ID的值,所以他在这一拿就行了,ID的值是三,所以相当于呢,我们就在这儿拿到了三这个值,它终于相当确定了第一个参数的值,那接下来呢,就是一些默认处理,我们不用管了,其他的这个默认处理它还给里边放,该放放第一个参数去解析,完了大家看啊第一个参数。
30:39
二个零,二个零呢,相当于我解析出来它是几了,它是三,然后呢,接下来便利循环其他所有的参数都是这种办法,好,那么接下来继续,接下来I等于一拿到第二个参数,第二个参数也是pass宝没问题,那么第二个参数标注了帕宝注解,然后呢,整个还是前边那一套。
31:02
先看我们哪个解析器支持这种参数,肯定是pass variable解析器,然后呢,支持以后呢,就来解析它的值,Step行图,然后呢,拿到这个解析器,我们直接拿到pass variable的这个解析器,拿到这个解析器以后呢,接下来解析值,解析值又是我们以前的这个方法,然我们现在呢,要解析的是谁呢?我们现在要解析的是name,那name呢,我们同样直接从里边我们就能拿到值,我们在这是要解析user nameme username的值就是它,所以呢,这就是我们pass variableable,好,那我们把这个pass variableable放行以后,那接下来看其他人怎么办,接下来呢,二个一参数的值就确定好了,对吧,是李四,所以呢,接下来我们来看所有的这个二个里边确定了两个值,第一个三,第二个李四,接下来遍利循环,每一个都这样,在第三个参数,我们来看一下是谁。第三个参数标了啥注解还是passver,我不想要passver了,我们来把它放行,来到第四个参数放行,好,接下来我们来看,哎,现在是二啊,然后呢,我再放行。
32:09
再放行。我们好,A现在是三了,I现在是三,以后呢,来看第三个参数,第三个参数呢,I现在是三,我们第三个参数它标了request header出解,来看它是怎么判断的,先来判断resolve,是不是支持step into进来进来,然后呢,他先来获取,获取到的先为空,因为第一次判断为空,将来便利循环所有的reserver,所有的reserver,首先第一个reserver request肯定不行,因为它是来看谁标没标request p注解,第二个呢,也不行,我就不进去了,第三个pass variable肯定也不行,因为我们现在。好,Pass,第四个pass variable也不行,第五个matrix variable矩阵变量也不行,第这个矩阵变量也不行,因为我们当前这个参数,我们来确定一下啊,当前参数呢,它是标注了request header注解的,所以我们来看。
33:04
继续来看我们的第七个。第也不行,然后呢,接下来request response body的这个解析器也不行,然后呢,Request也不行,然后呢request head得了,然后呢,接下来便利到了我们这个request head man的reserve来看它支不支持step into怎么判断,支持非常方便,只要你的这个参数标注了request header这个注解,并且呢你的这个参数类型不是map,也就是说我们request header标注的这些人,它呢,如果不是map的话,我就来到这个request header的解析器,如果是map,自然来到request header map的解析器,好,所以呢,我这个解析器就支持没问题,它现在支持把它的整个判断结果放到缓存里边,方便我们下一次取好现在拿到解析器了,然后呢,接下来我们拿解析器解析参数的值step图进来拿到解析器,这个解析器呢,我们上一次判断支不支持。
34:08
而已经判断过了,所以这个缓存里边你想要获取直接走起我们这个缓存里边就能拿到这个值,所以呢,我们就不用再来进这个编离过程了,哎,这一块原码设计呢也非常好,然后呢,我们来到了这个,拿到了这个解析器,然后我们来调用解析器解析这个值,来看request p怎么解析这个值的,那就在这儿,首先呢,拿到这个参数的名字啊,我们这个要解析的这个参数的这个名字,Name的value info,这个参数的名字呢,叫user agent,它怎么解析的。好,拿到我们要解析的这个参数名叫user agent,真正的解析值在这我们来看它怎么解析的,Step into进来,然后呢,非常非常简单的一个解析办法,就是调用大家原生的request get header values,获取某一个属性的,相当于获取我们这个请求图的值,这就是我们service里边的原生方法,得到这个值以后,哎,我们得到user agent的值是这么一大堆,但是我们user agent,因为我们要封装的是一个string类型,人家呢是调用head values,咱同一个head可能有人家有很多值,人拿到这个数组以后呢,只给你返回第一个。
35:23
大家会看到,如果数组长度为一,就给只给你返回第一个,否则呢,就给你返回now,好,这时呢,人家终于相当于调用底层的API,给我们拿到了head的值,这就是我们整个确定的每一个值的确定,其他的老师就不便利了,都是一个增强for循环。主要核心就是这个增强放循环,每每一个参数就来确定,先看哪个解析器能解析,然后接下来看我们这个解析器啊,怎么解析,就是我们的这个过程,所以我们这个参数位置到底能写哪些东西,其实就在这handle method argument receiver,来,我们来最终给大家来参数解析器,参数解析器的这个基本类型是在这儿,所以老师怎么给大家分类得到了啊,我们说现在我们的能支持这么四四大种,四大种这些参数呢,我只记记得我们之前在这儿。
36:22
请求映射处处理,我要能支持RISK1大堆能支持我们的这个,包括能能能支持我们这个注解一大堆,能支持我们sole api1大堆,复杂参数一大堆,为啥能支持?就是我找到了所有的handler method argument receiver,然后每一个reserver,我看它支持啥,比如我们来看这个,我们的这个,呃,比如我们来随便拿一个吧,这个叫redirect attribute method的receive,我呢一看它支持叫redirect attribute,属性说明我们这个参数位置呢,就能写一个属性,这个属性名叫redirect attribute,你写了它,那我们的那个参数解析器就会起作用,所以呢,这就是我们整个的参数解析原理,挨个便利循环,用所有的参数解析器来做就行了,来,这个原理呢,大家在里边自己也要多debug一下去来体会。
我来说两句