00:00
那前面呢,我们说了一下rest的使用原理,我们再来看一个请求映射里原理就是说我们每次发请求,它呢到底是怎么找到我们哪个方法去来处理这个请求呢?因为我们现在知道在spring BOO中,所有的请求过来都会来到dispaure sol,因为spring boot呢,底层还是使用的spring m VC,所以spring m VC的整个dispar sol是处理所有请求的开始,那所有请求的开始呢,它的整个请求处理方法是我们可以来找一下,因为dispure sol说起来也是一个S,继承于framework soet又继承于htp so b,然后又继承于HTP,那说明呢,它是一个so,它必然要重写do get或do p之类的方法来CTRL f12打开它的整个结构,哎,我们发现呢,这里边没有do get或do post,那说明在它的这个子类里边,我们看有没有重写它的整个继承数是。
01:00
Framework sol到htb sol b,好,我们把它的整个这个继承数我们来给大家打开。那在这个继承数里边呢,我们原生的sole是这个HTTPSO,那在这个sole里呢,本来应该有do get或者do post方法,我们此类要重写的,但是呢,我们发现在HTPS里边我们没有找到,所以呢,我们就要看在framework这个里边有没有好,我们现在呢,在画图里边,我们把这个编辑打开,那我们现在来到framework,我们看它有没有重写do get或do post方法,HTV原声的do get do PS我们来找一下,我们直接来搜do。诶,我们发现呢,这有do get do posts,诶,它相当于重写了,大家看这个镜头这样呢,都是重写了原生的http select方法,我们来到这个do get,我们随便来到一个,我们发现呢,无论我们是来调用do get do post还是什么,他们呢,最终都是调用我们本类的process request,说明我们这个请求处理开始我们的HV的do get,我们把这一块记录一下,Http server的do get,我们把这个字稍微调小一点,它里边的这个do get,最终呢,会调用到我们的这个framework serve,调用到这个里边的process request。
02:25
好,我们把它拿过来process request,然后呢,这个process request们来看一下它做了什么,我们就知道请求该调用谁了,点进来process request里边,那前面呢,都是一些初始化过程,都是获取,呃,获取各种值,获取各种值,然后set,这都是些初始化过程,那核心的大家看这一块TRY,哎,我们尝试执行一个方法,执行完以后呢,各种又是清理过程,所以呢,Do service这才是最核心,在framework里边有一个do service,就是process request,又调用它本类的do。
03:00
那我们的这个do service,我们再来点进去来看do service点进来do service呢,它由由于是一个咱们这个抽象方法,它也没有重写,这没有实现,所以呢,自然来到此类里边dispature crl f12,然后呢,我们就肯定会发现我们的这个方法叫do service dispenture service ctrl f12,然后呢,我们来找do,诶确实呢,这有do service,也就是说呢,在最终的dispenture service里边对do service做了实现。Dispure里边,它里边呢,有do service的实现,然后我们一连串请求一进来,应该是调service的get,最终调到它,调到它最终才调到dispure service里边的do service,而它里边的这个do service呢,我们看还是一大堆,哎,各种set,这都是一些初始化过程,只要大家看get set都是给它里边放东西,初始化过程我们就来看核心的方法调用,我们发现呢,这有一个串叫dode punch,哎。
04:03
做转发意思,我们把这个请求做一个派发,然后呢,Dotypach点进来,我们发现呢,这里边才是一些真正有功能的方法,什么check multi part,检查我们这个文件上传,然后呢,包括每一个重要的方法,人家这都有注释,所以呢do dispatch才是我们dispaturele里边最终要研究的方法,每一个请求进来都要调用这个方法,这是呢,每个请求,每个请求都会调用我们这个方法,所以呢,我们要说我们这个请求映射原理,包括研究我们spring boot以及spring m VC,我们整个处理的这个原理,我们要从dopach开始分析好,我们把这个图呢放到这。也就是推荐大家我们所有的这个对spring mvc功能的分析,Spring mvc功能分析,分析都从我们哪个方法开始呢?都从我们这个disppature control home,都从我们这个类里边的do dispatch方法开始,把这个copy reference都从我们这个里边的,咱们什么方法呢?它有一个do dispatch来找一下CTRL f12do dispach。
05:16
好,我们从这个方法开始,所以呢,这是来处理所有请求的方法,那自然而然我们分析到了这个架构,我们就给他这儿打一个断点们来看整个请求处理,包括他是怎么找到我们某一个请求,要调用谁来处理的,我现在呢,把这个关掉,我们一八个模式开始。Debug模式呢,我把其他之前的断点删掉,就只留了一个do dispa sol的1001横的这个断点,好,那么先来来看一下我们的这个功能,如果我来发送请求,我们先来访问我们的首页,好,首页我们发请求,我们先直接给他放行过去,放行过去,然后呢,我们访问我们一个真正的请求。我们来看一下它是怎么找的,比如我们来访问一个rest和get提交的这个请求,比如说呢,我们会发一个相当于这个请求,我们来看它整个的执行过程,传入原生的request和response,这都是HTV一连串调用下来的。
06:14
然后呢,点进它里边,我们发现呢,整个请求的路径是杠user,诶这个请求的详细信息都在这,请求的路径是杠user,相当于我们现在发送了一个user请求,那发送一个user请求以后呢,接下来我们来看它怎么找到,要用谁调用的,往下翻它呢,相当于先把原生的请求拿过来包装一下,然后呢,我们再来过来,这有一个叫handler的执行量,我们后来再说,然后呢,继续说multi part request是不是一个文件上传请求默认是false,然后呢,包括我们整个请求期间有没有异步,如果有异步使用一个异步管理器,我们这一块呢,暂时不用管,然后注意这有一个model and view,这些都是一些空初始化的数据,我们暂时不用管。然后接下来看我们第一个有功能的东西,东西在dotypa里边第一个有功能叫check multi partt,检查我们是否文件上传请求详细内容我们文件上传再说,然后呢,如果是文件上传请求,他在这儿来进行一个转化,然后接下来在这。
07:14
注意,我们这有一个叫determine handler for the current request,就是我们来决定是哪个handler能处理当前请求,如果我把它放行map handler,我们就会看到它呢,直接给我们找到了hello controller get user方法能处理这个请求,所以神奇的地方就在这,它到底是怎么找到我当前这个杠user请求会要调用那个方法来进行处理的?哎,我们当前是杠user请求,它怎么就能调用这个方法处理,那么断联呢?打到这儿,我现在重新对八开始。来看一下它的整个逻辑。所以说呢,我们的核心我把这一块复制过来,我们去来研究这个方法,我们就能知道我们这个它是怎么找到它整个请求的映射原理,在这一块它是来找到,找到,找到当前请求,当前请求使用哪个handleler处理,所谓的这个handleler就是我们编写的controller handleler呢,那不就是处理器吗?我们使用哪个controller的哪个方法来处理,Controlrler的方法来处理就行了,我们在这呢,它就要找,它怎么找呢?我们就进来,好,现在呢,断点我们放到这儿,我们现在重新来发送请求,我来刷新,我们现在访问的是userr路径,我们来看它是怎么找的,好,我们把第一步的这一个断点放到这儿,我们直接放行到我们这一步get handle了,它要依据当前请求,当前请求里边肯定有我们现在要访问的哪个URL地址,这是HTP传过来的,不用管,Step into进来,然后。
08:50
那大家注意,这有一个东西叫handler mans,诶也就是获取到所有的,我们来看一下这个handler mappings呢有五个。
09:01
它从所有的handler mapping handler mapping呢,我们现在来看,我们的第一个核心的这个东西叫handlerping,我们翻译过来呢,其实就叫处理器映射,也就是说我们spring m VC怎么知道哪个请求要用谁处理,是根据处理器里边的映射规则,也就是说杠什么请求,然后呢,谁谁谁来处理,都有这个映射规则,而这些规则呢,都被保存在handle mapping里边,那默认呢,我们现在有五个handle map。其中呢,有几个handle德ler mapping,大家可能熟悉,就是这个叫welcome page handle德r map品大家还记得不?我们现在呢,有一个相当于我们现在五个handle map,有一个叫welcome page欢迎页的处理请求,哎,我们之前说资源规则的时候,我们发现呢,Spring m Mac自动的给容器中会放一个欢迎页的这个handler machine,然后这个handler machine里边呢,我们来看它里边也有保存规则,保存什么规则,就是我们所有的这个index请求,哎,你的这个,比如这个pass me,我们这个路径匹配,路径匹配就是杠,当前项目下的这个杠,你直接访问杠,直接访问杠,我给你访问到哪了呢?我们这个杠直接会无U,大家看啊,整个我们这个视图直接把我们跳转到相当于index htm,所以呢,相当于我们首页到底能访问的是我们这个韩德map里边保存了一个规则。
10:30
这是我们就导致我们现在有首页的访问了,而我们接下来还有一个叫request map看到了。我们来点进来看,在所有的handler mapping这五个handler mapping里边,还有一个叫request mapping handler mapping,我们把这个copy value这个拿过来。就是这个request map handle map ctrl v,诶,我们把这个名字我们来给它拿过来啊。Request mapping handle mapping。
11:02
GET0,我们获取到了这个request,这个copy value6现在copy不到。我们来直接ctrl n request map,看到了map,然后说呢,我们相当于以第一个组件是它,然后呢,它的作用就是,诶大家看什么叫request map,大家有没有注意,我们以前有一个注解叫request map,所以呢,接下来相当于是request mapping注解的所有的处理器映射,也就说这个东西里边它保存了所有保存了所有request mapping和handler的映射规则,而它又是怎么保存的?那其实是我们这个应用一启动spring mvc自动扫描我们所有的CTRL了,并解析注解,把你的这些注解信息全部保存到我们这个handle mapping里边,所以呢,接下来它会从这么五个handle mapping里边,大家注意一个增强for循环,它相当挨个找我们系统里边所有的请求映射,看谁能处理这个请求,而我们来看找到我们第一个hand德map第一个。
12:09
Handle拉mapping相当于就是我们的request mapping handle mapping,它里边保存了哪些映射信息,我们一直往下翻,这有一个叫mapping regry,相当于我们这个映射的这个注册中心,这个中心里边呢,大家打开你就会发现我们当前项目里边,我们自己写的所有的这个路径,它在这呢都有映射我们自己写的这个bug JPG,它是由哪个controller处理的啊,哪个controller的哪个方法,包括这几个userr是由哪个controltrler的哪个方法,包括呢,系统里边spring boot自带的这两个error处理,它都是哪个ctrler哪个方法,所以呢,这都有,所以相当于是我们的request mapping handle mapping里边保存了我们当前系统每我们自己写的类,每一个类里边的每一个方法都能处理什么请求,那那接下来就好说了,既然我们都知道了,那接下来你说我当前请求,我当前请求叫杠user子叫杠user,那谁能处理呢?
13:09
啊,我们便利到第一个handle德mapping的时候,相当于它的这个注册中心里边就能找到我们这个杠userz是谁来处理,所以最终在这就决定到了是hello controller get user来处理的,所以它在这mapping里边get handleler,从我们handler mapping里边获取,我们的这个handleler就是处理器,我们来点进去,进来看一下,然后呢,在这get handler internal们来获取,怎么获取,点进来看一下,好这呢都是先移除一些什么,我们不管,然后呢,Step into进来看一下就行了,他怎么看呢?先拿到我们原生请求,我们现在想要访问的路径,他拿到look pass,哎,他想要看我们访问的路径呢,是杠user,然后呢,带着这个路径,他还拿到一把锁,对吧,害怕我们这个并发查询,我们这个mapping registry,这mapping registry呢,我们也看到了,是我们这个handler mapping request mapping handler mapping里边的一个属性mapping registry,它里边保存了我们所有请求调用。
14:09
哪个方法处理,所以呢,它最终相当于是在这里边,然后呢,大家来看我们要找这个路径啊,我们这个当前请求,这个路径到底谁来处理,来,Step into进来,Step into进来,然后传入了两个东西,第一个我们当前啊,当前我们要找到路径,第二个我们原生的这个请求,然后呢,接下来他就在这儿找,从我们这个registry里边,对吧,使用我们的这个路径,然后呢,他就去找谁能处理,那问题其实就在于我们现在的这个RY里边,像request map handler map里边它的这个路径,光杠U的这个请求,其实有12344个人的路径都是这个,只是请求方式不对,然后呢,我们来看他是怎么找,先是根据URL找找杠U子,他先不管这个请求方式,所以呢他会找,我估计他能找到四个,我们来看,诶,确实呢,找到四个get post put delete方式的user,找到了以后呢,接下来他把所有找到的想要添加到我们匹配的。
15:09
这个集合里边相当于他找到了四个,四个呢,如果没找到,哎,这儿还有一个,如果没找到,他就填一些空的东西,然后呢,接下来看,如果找到了,而且不为空,不为空,接下来呢,他matches get0,相当于他把找到的你里边的第一个拿过来,把第一个拿过来。第一个呢,如果他同时找到了好多,他就认为第一个是最匹配的,而且呢,如果他,而且大家注意,如果呢,我们现在这个matches.size大于一,也就是说呢,我们相当于同时找到了非常多我们的这个matches,大家注意啊,这个matches它是在这儿我们找到的呢,在在这一块我们找到了四个,然后呢,他把这四个呢,最终调用这个方法获获取到我们这个能匹配的集合里边,但这块匹配呢,我们刚才没进去,他肯定按照请求方式就匹配好了,所以最终给我们留下我们最佳匹配的这个matchs集合里边只有一个啊,只有一个啊,然后呢,他就拿到这个,我们相当于这个matches呢,已经是得到我们最佳匹配的,如果我们现在相当于你写了多个方法,同时都能处理get user算请求。那你的这个match。
16:24
就能大于一,那一大于一以后呢,接下来他各种排序排完以后在这儿给你最后再测试,把你你都能匹配的这一两个全部拿来给你进行对比,最终比完以后会给你报一个错,说相当于我们这个handle德ler啊handleler呢,你能处理这个URL uri处理这个路径呢,有两个方法都能处理啊,说明呢就会抛出异常,所以呢,也就是spring m VC要求我们同样的一个请求,同样的请求方式,不能有多个方法同时能处理,只能有一个,那就落脚在这儿了,所以我们最终呢,找到我们最佳匹配规则,就是get方式的userr能匹配,而get方式的userr呢是谁?就是我们这个CTRL的get user方法,所以简单总结起来就是一句话,怎么知道哪个请求谁能处理,就是所有的请求映射都保存在了,所有的请求映射都在handler mapping里面。handler mapping中。
17:23
满屏中。而我们这个系统里边呢,有一些默认的handle handler map,比如我们这个spring boot,大家看啊,我们这个springt呢,一启动给我们自动配置了这个welcome欢迎页的hand,所以呢,Spring boot自动除了配置欢迎页。的handle map,所以呢你访问欢迎页啊,Index页面,所以呢,我们看到的效果就是访问杠,访问杠能访问到首页,能访问到index页面,Dex.HTM能访问到的原因就不是我们这个request map handle mapping能处理的事情了,好,我把它重新debug,比如我现在就来访问杠,我来访问杠,因为我们说系统里边所有的handler mapping我们这都找到五个呢,所有的handler mapping合起来都给你帮你找你的路径,谁能处理?所以呢,假设我现在重新换成我来访问系统的更路径走,我如果来访问更路径,我们来看我们的这个debug有没有进来啊。
18:35
Request mapping handler mapping把这一块debug进不来了,我们一定把这个bug断点呢打到这儿,他要找所有的handleler mapping来看,来刷新好进到首页,现在呢,我们来请求一进来我来放行,放行呢他来找我们当前请求,当前请求我们来看是访问什么的请求,访问杠的请求没问题,看谁能处理,我们来直接step into,然后呢,接下来就进入了便利循环,所有的handle maping的啊。
19:04
时候了,然后呢,我们先来找到第一个handle德栏map屏,第一个handle德栏map屏呢,由于我们这个里边映射只保存的相当于是我们自己ctrller写的这些路径映射,没人能处理杠,所以你如果在第一个里边找,你找到的这个handle德ler肯定是空的,来我们看到找到是空,如果是空的话呢,就继续for循环,那for循环呢,相当于来到第二个handle德ler map,第二个handle德ler map呢叫welcome page,我们welcome page这个handle德ler map呢,巧了,它正好处理的这个路径就是杠,所以呢,我们现在在这step into,我们要找就找到handleler了,而这个handleler是什么呢?就是我们spring mvc里边默认处理我们这个index页面,人家给我们的able,我们的UCTR了,哎,就是这个,所以呢,相当于我们现在就我们访问index页面就有人了,所以这就是我们整个handle map的匹配规则,所有handle map全部来进行匹配,谁能匹配用谁的。
20:03
我们来看一下这个,我们为什么这个标号不能用了。好,我们把这个标号打上,所boot自动配置了欢迎页的handle handle machine,然后呢,大家要注意的就是所有请求一进来,请求进来,挨个挨个尝试所有的handler mapping,所有的handleler mapping,看是否有咱们这个请求信息。如果有啊,如果有,如果有就找到这个请求。找到这个请求干嘛?呃,对应的handle德ler,如果没有就是下一个handle德拉,这就是我们这个富土康质检员,哎,我们这就跟捡手机一样,对吧?如果没有呢,那就下一个了,那下一个呢,我们这个请求进来,只要找到handle m,那剩下的这个步骤,哎,我们来看啊,找到了handle德ler,找到了handle德ler真正能处理请求的,然后呢,后边才是来执行我们真正业务功能逻辑的,那后边的原理我们后边再说了,所以呢,我们现在能看到的就是我们的handle mapping的整个工作原理,而spring boot为我们配置了哪些handler mapping,我们来到web mvc auto conffi里边,Auto conffigu里边来可以看一下,在spring BOO呢,我们底层给我们配了第一个,我们来往下翻,我们来往下翻吧。
21:35
呃,首先嗯,我们来找一下。有没有跟handler mapping有关的,好,首先大家来看啊,第一个request mapping handler mapping现在于boot呢,给我们容器中我们看到的第一个handler mapping是boot给我们容器中放的这个默认的这个组件呢,就是来解析谁的解析我们当前当前所有的这个方法,标了request map注解get put都一样,标了这些注解的时候,哎,他整的,所以spring BOO给我们自动配置了它,这是第一个spring boot自动配置,Spring boot自动配置了默认的。
22:20
这个request map handler map,它呢也配置了welcome page handler map,所以呢我们能看到欢迎页的这个看到了man,所以呢我们欢迎页也能访问,然后呢,接下来包括哎我们这个系统里边还兼容的这个b name URL,看到了maning RO function这些功能呢,我们后来再说,所以呢,这是我们整个handler mapping的逻辑,所以如果一句话,我们我们需要一些自定义的这个映射处理,需要一些自定义的映射处理处理,我们也可以自己给容器中,我们也可以自己给容器中放咱们这个汉德拉满品,所以呢,其实汉德拉满品大家呢应该掌握了,它呢就是保存每一个请求谁来处理,每一个请求谁来处理,甚至于是什么呢?比如我当前项目我发一个杠API。
23:20
哎,我们经常呢,自定义handle德map用这个场景,比如API,我们呢,API分版本,V1版本下的我们获取用户跟VR版本下的获取用户可能呢不一样,那V1版本呢,调用哪个,VR版本调用哪个,那这个东西呢,可能就不只不仅仅只是我们这个controller的变化,我们希望呢能自定义handle mapping的规则,如果是V1版本所有的这个请求呢,给我去,比如我们哪个包里边找,如果是VR版本所有的请求给我去哪个包里边找,这样呢就会非常方便,所以呢,我们未来也有这个自定义看mapping的这个场景,自定义看德了卖屏。
24:03
好,我们有时间呢,也可以给来给大家讲一下自定义含德品最终在我们生产里边的使用,这是我们整个请求映射的原理,通过我们一步步一步一调用,然后在hand map里边发现我们哪个请求谁能处理,然后呢再来去调用人家的方法就行。
我来说两句