00:00
各位同学大家好,下面呢,我们继续完成手写润实现IOC功能,刚才呢咱完成了以上几个步骤,第一步我们建了一个子模块,然后第二步我们创建了测试类,包括service,包括DA,第三步呢,我们建了两个注解,一个叫B,一个叫Di,然后后面实现通过B来创建对象,通过Di完成属性注入,然后最后写了一个接口,一个实验类。这个接口就是咱们的B容器接口,我们还是叫这个,然后里边有个方法,方法就返回这个对象,另外有这个接口实类我们叫在里边我们首先建立一个map合的属性,用它来存储我们的对象,在map里key就是class,它的value就是我们的对象,然后这个方法种回。另外最后我们写了一个有构造们后面在里面会传入咱们的包的径,根据包的路径设置扫描规则,就是我们之前提到的当前包及其子包,我们看一下哪个类上边有爱的B注解,有的话把这个类的对象用反射精视例化所在下面把这个构造给它完成设置包的扫描规则,最终反射创建对象。
01:26
那咱们看这个该怎么去做,首先啊,这里边我先说明,比如说咱们后面要用的话,就是跟之前死人一样,只是说类,咱换成我们自己这个类,咱们也是OB,注意啊,这类要导的是我们当自己这个T,比如我们叫T,等于一个叫也是我们自己这个里的,然后在里边传什么,传的是我们径,比如传一个com.at硅谷,咱传它这样的话,它就根据这个规则进行扫描,咱们这个包及其子包中那种,然后咱们用contact里边这个方法。
02:10
我们写一下,刚才咱们看到叫get b里边你的class最终得到你的对象,然后后面用肯定是这么来使用,所以下面我们就根据这个包的路径来设置一下它的扫描规则,那我们在里边我们来写一下这个代码。首先给大家先做个分析,咱们看该怎么去做,各位注意啊,我们要传的参数值是不是应该是这个样子的,就是com.at硅谷,当然你可能有更多层的这个包,比如叫四六,咱传的肯定是这个样子,那这样的话咱肯定没法扫描,那咱怎么做,是不是要找到这个包所在的路径了,因为大家明确啊,在我们招入项目中,这个包是不是就是一个文件夹,那我就找到这文件夹在的路径,咱们找到它的绝对路径就可以了,然后找到这些路径之后,看一下这个文件夹里边是不还有子文件夹,而这里边是不是还有文件,咱们依次进行递归,最终找到类上边有没有注解是不是就可以了。所以下咱就来做这个事情。
03:16
那怎么做,给大家先简单分一下步骤,首先啊,我们里边的第一步操作,咱做法就是因为这个写法中是不是一个点呀,那咱把这点是要换成那个斜杠,因为路径是带斜杠的,肯定不是点,所以第一部分。把里面这个点。给他就是替换成。这个斜杠,这是我们要做的一部分,然后替换成斜杠之后,第二部分就是第二部咱们要获取一下这个包的,它的这个叫绝对路径。把这个得到绝对径,也就是说咱们说那个带盘当前那pass里带盘径家注意啊,我们这里边得到路径呢,其实并不是这个路径是你最终编译之后的这个路径,咱们看到这里边有一个叫target,在里边是不是有这个最终编译之后的部分是咱们的点卡S文件,然后得到的是这个内容,是你编译之后的这个路径,这个过程咱们把它又得到,这是我们的第二部分,那咱们看这个该怎么去做,给大家写下啊。
04:31
首先第一步我们先做一个替换。那咱们做个实现,用base package里边一个方法叫replace o,咱们做个替换,把里边的点,因为点它有转移,所以咱加上一个转移符号,替换成这个斜杠。咱们加上转义啊,就写上这样的话,我们完成了一个替换,然后给它起个名字,这个名字我们就叫这个。Package。
05:01
Pass,那就叫这个名字。就是包的那个路径。Pass。这是我们做的一个替换,然后这个之后我们继续来做,下面呢,要得到这个包所在的绝对路径,就是带盘符的路径,那这个怎么得到呢?给大家写一下啊,大家可以这么来写,通过当前的这个线。叫卡润桃。Thread里边有一个方法叫get contestlo,这是什么?是不是类加载器通过它来得到,然后在里边呢,有一个方法叫get resources,这个resources,然后在里边传入咱这个package pass,这样的话得到就是它这个绝对路径啊,通过resources给他得到。然后最终返回的是一个是一个枚举对象啊,给起个名字,我就叫这个,呃,DRS了,就叫它了啊,或者叫uls啊,这都可以啊,现在把这得到,然后得到之后呢,这里边有异,加上一个开给处理一下。
06:14
我加个拆开啊,都给它放到这个拆开里边去了。给他拿进来,所以现在把这得到,然后得到之后从里边把路径我们要给它取到,因为是一个枚举对象嘛,咱给他做一个便利,加上一个。里边用这个us点上方法这个s elements,然后得到。里边的具体值用的element得到的是一个URL,是它那个绝对的径,这就是绝对路径,但这绝对路径得到的时候呢,里边有一个小问题,就是斜杠,他可能做了一个URL编码,一会咱会底盘会看到这个效果,咱再给他再做一个转码的一个实现。
07:00
用ul这个叫。以code里边的一个方法啊,应该这个ul啊。里边一个方法叫抵扣的,加上这个Ul.get file,然后咱们用的编码方式,咱就用这个UTF杠八,这样的话得到才是我们最终这个完整的绝对路径啊,大家给他起个名字就叫pass。这样的话,我们就可得到以上是咱们写的这么一段基础代码,然后这个写完之后,咱把它呢做一个测试,我们试一下这个效果,看目前它是怎么样的,咱们一点一点来看。那怎么测试,为了测试方便啊,我这么来做,呃,这个方法呢,我先临时改个名字,一会儿咱给他再改回来,为了咱们操作方便啊,咱给他先改个名字,为了测试方便,比如说我就写一个词ID考。这个方法我就叫PASS1啊,就叫他了啊。
08:04
然后咱们做个测试,下面呢,我加上一个问方法。咱直接把它来测试一下,试一下这个效果,Pass demo1,比如说里边我传个路径,com.at硅谷,那咱们做个测试,这个测试为了各位看得更加明确,我通过bug方式来测试一下。那咱们啊,看一下这个具体效果,我把代码先稍微调整一下啊,方便咱们看的更明确。这是那个替换。然后这里边是得到绝对路径啊,这是做那个。转码的过程。抵扣的过程,最终这里边有那个值啊,咱们把它可以做一个输出pass,然后现在我加上断点,咱们来看一下目前的过程是怎么样,我们来试一下啊。大家看,首先第一个我这个base package是com.at硅谷咱们首先把它做一个替换,然后大家看替换之后变成是不是就斜杠啊,把点替换成斜杠,因为这里有转嘛,加上这个值,然后替换成斜杠之后得到它这个绝对路径,就是咱们完整的这个绝对路径,那咱们往下执行,大家看啊,这个ul得到的是一个枚举,咱们把它做过便利,然后得到一个ul,大家看ul是不是一个完整路径。
09:31
啊,就是file冒号加上盘符的完整路径,但是你看那完整路径中有一个小问题,就是刚才我这个斜杠它变成的是什么?是不是一个转移的叫百分号五,还加个C,那马它要转回来加什么叫抵扣的,那我们再执行,大家看file pass里边得到的是不是最终这个完整路径,所以咱们现在把这个路径就得到了,就是我这个包所在的完整路径。
10:00
这个我们写到这里,然后写到这里之后我们继续往下来写。下面我们写什么呢?就是根据这个路径咱们进行扫描的这个设置,就是进行包及其子包中如果有注解进行对象创建,就是包的这个。扫描的过程,那这个过程呢,我单独写个方法,我就叫漏B。然后把这路径直接进去啊,咱们上一个file,加上这个叫file pass,然后在B里边最终完成这个扫描过程,我把这方法在下面我们做个创建。我写一下就是包扫描的这个过程,然后创建或者说让我们那个B进行实例化。这个咱们一会儿来写,然后这过程中呢,为了咱们后面方便,我这里边简单做这么一个事情,大家注意啊,我们刚才给大家看到,我这里边有一个完整的路径,大家看这路径是不是这么长的路径,然后路径中你发现啊,这一部分是不是叫class,就是它是代表我们的类的这个部分后面是包,而我实际中后面用到的其实主要是后面这部分前面径都是固定的,那我这里边我做个截取,就是把前面就是包前面部分给它截据出来,为了后面咱们操作方便。
11:20
那我来截取一下啊,怎么做呢?我的后面使用方便,你不做也可以是后面还需要重复做这个事情,那我这么来做,我在外边定义一个成圆的静态的一个变量,就这个此。我叫root pass写到外边。为了后面方便啊,你不写也可以,咱为了操作方便,然后在里边我把这个pass做一个截取。写一下啊,获取它包前面的这个路径的部分,给它进行字符串的截取,那咱写一下啊,这各位应该都清楚啊,Pass里边有一个方法叫sub string,咱们从第零位到我们这个完整位置,那怎么写呢?我们可以用这个。
12:11
Pass这个LS,然后你那个的那部分部分应该pack pass。点认识,咱给它做个截取,这么截的话,最终就是得到前面这部分,然后把包前面部分给它最终得到,所以咱们写这么一个结构,为了咱们后面方便,最终给它赋值,咱刚才写那个叫root pass里边。我写到这里,Root pass。所以现在啊,做了一个准备,为了后面使用,而现在这步做到了,那下面呢,我们就在这个漏的B里边完成这个包的扫描过程,咱们最后就来写这部分,那咱们下面开始写这个代码,这个代码怎么做?同样啊,给大家先做个分析,然后咱们一步一步进行实现。
13:07
咱们先分析一下这个过程啊,我把步骤先写一遍,我是这么一个习惯,先把步骤写明白,然后咱再一步一步往里边再填入代码。那咱们看一下什么步骤啊,首先第一步操作,因为咱们传的这是不是一个包的路径啊,就是你的文件夹,所以咱第一个先做个判断,就是写的更严格,我这里写的详细点啊,就是我们先判断。当前的这个内容是否是狗文件夹,如果说你不是文件夹,那就表示不是包,那咱就不往下进行扫描了,因为它必须是一个文件夹才可以。第一步做个判断,如果不是,那咱就不需要做这操作了,然后第二步如果是文件夹,那怎么做,咱就是获取一下。我写一下啊,获取一下文件夹里边的所有内容,这内容包括这里边可能有文件,可能还有文件夹,就是咱说它的包,就是里边还有子文件夹,这里边做个获取,获取之后第三步咱做个判断。
14:10
如果说啊,它这个文件夹里边内容为空,就是里边什么都没有,那咱就直接返回,表示里边还没有类,或者你没有编译,没有这个代码啊,那表示单没有完成,这个就写的更完整点,这是前三步,我再说一下啊,第一步先判断当前这个file是否是文件夹,如果你是文件,那咱就不需要扫描了,因为咱这个传的是包,它肯定是一个文件夹,如果是文件夹,然后去里面所有内容,如果内容为空,那直接返回,表示里边没有东西。然后再写第四步,如果说这里边不为空啊,就是如果。文件夹里边不为空,那咱往下来做,那怎么做呢?咱们就遍历这个文件夹里边的所有内容,因为你得到所有内容肯定是一个数组的一个形式,咱们把它做一个遍历,遍历里边所有内容,然后遍历过程中这里写一下啊,我写成4.1。
15:09
就是便利得到每部分内容,或者说每个那个file对象详细点啊,得到每个file对象,然后咱们继续判断。判断什么呢?如果说啊,他就是还是一个文件夹,那咱们给他做一个什么,就是咱说的递归,继续给他判断,继续以此类推,所以咱们做这过程,如说我现在比如我传的是com at硅谷,当我一发现A硅下边还有文件夹,那咱们继续便利,看下边是否还有文件夹,以此类推,做一个递归的便利,直到里边没有内容。然后这是4.1步,咱们再往下写4.2。如果说啊,便利得到的这个file对象,它不是一个文件夹,就代表是一个文件啊,不是文件夹,那肯定就是一个文件,那是一个文件的话,那咱们要做个处理,做什么处理呢?这里强调啊,给大家说明,因为得到一个文件嘛,那这个文件我们得到之后,咱是不是要把文件那个就是判断它上面有没有注解,就是咱说那个艾特B的注解,如果有注解把对象创建,没有注解那咱就不进行对象创建,咱肯定做这么一个处理。
16:35
那我把这步骤啊,咱写的更详细点,如果它是一个文件啊,我们写4.3这个步骤。那首先我们肯定要得你就是那个的径的上你的类的那个名称的那部分,什么意思呢?比如现在啊,我得到这个完整路径,假如说咱们是这么一个路径,呃,我找到啊,这里没有,比如说我现在举个例子啊,比如现在我得到的路径,假如说是里边的这个什么C盘,什么六加,什么B,最终它变之后是不是一个点卡的文件,而我想得到是什么,就是com包开的部分,比如说com-ad,硅杠AO-B,想把这部得到,得到之后咱才用反创建对象。
17:21
所以咱们啊,需要把这个包路径加类的部分得到这一部分做的那就是一个字符串的截取过程。这咱们之前做过啊。就是刚才咱们写的这个就用到了,因为咱们之前截取过前面部分,你通过它一截取可以得到这部分,然后得到之后,下面写一下4.4步,咱们需要判断一下,就是当前文件的类型,是否是这个类型,就是这个类型,或者说点class,因为它是字节码文件,如果是的话,那咱们进行反射这个操作。啊,解架4.5步。
18:02
如果它它是点class这个类型,那咱怎么做,咱你可以理解为我现在就是把这个路径中的斜杠给它替换成这个点,变成包括啊替换点之后还有一件事情要把那个点class部分给它去掉。为什么去掉呢?各位明确,咱们得到类class应该是写com.a硅谷,点你的什么类的名称,应该没有点class,也没有斜杠,所以把这些都需要做处理,最终看到的应该是这么一个样子,我就简单写个事例,比如说at硅谷啊,点上这个service。比如我们叫这个点上这个userl,应该得到的是这个样子,通过它来用反射能见对象,这是我们做到的啊,然后写一下就是下一步骤,4.6步咱们得到之后,那我们就使用反射。
19:06
进行这个就是实例化啊,进行这个操作,但是实例化之前咱不要马上着急,实例化这里边还有一个特点,因为不是所有类都实例化,咱要还要做个判断,所以我强调啊,这一过程就是判断过程比较多,我先把总体流程说一遍,给大家一会儿再总结一遍,然后最终用代码,咱再一步一步把它写出来。咱们继续来看啊,如果说你这里边是文件,咱判断文件是否是点卡类型,如果是这个类型,那把路径中的斜杠替换成点,把点卡去掉,最终变成就这个样子,然后变成这个样子之后,下面呢,咱们还要做处理,就是判断一下我这个类上边是否有咱们这个注解,就是里边这个叫艾B这个注解,如果说有的话,那咱们再进行这个实例化的这个过程,没有的话,那我就不进行实例化,这是4.6。
20:06
然后在实例化的时候,还有最后一步,咱们把这个对象实例化之后。是不是要放到咱的map集合里面去,就要放到我们的这个里面去,B factor这个map集合中去。往这边放,然后放的时候呢,里边有一个细节的部分啊,大家看我的课件里边,我们就直接看一下,一会咱会写一遍。大家看这里map是不是K外表,就是如果说我这里做了一个判断,如果说你当前这个类啊,它有接口,那咱怎么做,让接口class作为key,如果没有接口,当前这个class就是我们的key啊,所以这里边有一个接口判断,就好比说咱们写那个user service等于new user service实现类接口等于new,实验类的对象跟它类似,有接口,让接口作为那个key,没有接口,自己的class就是key。
21:00
这个位置做了一个更详细的处理,最终都放到这个map里面去。以上啊,就是咱们说的一个基本的步骤,咱们把这个做一个说明,那我下面啊给大家再来重复一遍,最终我们写一下这个具体代码。首先啊,我们的第一部分,因为咱传的是一个包的路径,就是com.at硅谷这种形式,所以咱做法就是把点替换成斜杠,然后替换斜杠之后得到当前包的绝对路径,为了能进行文件夹的扫描,然后咱便利得到这路径,当然路径得到过程中,刚才咱们看到了里面有那个转译给它,再转回去,最终有一个截取,这后面使用通过路径咱们来包扫描,在扫描过程中我写了以下这么多步骤,那我们来看一遍啊,第一步判断当前是否是文件夹,如果不是文件夹,那就不需要做了,是文件夹表里面所有内容。文件夹里面如果为空,直接返回。
22:01
部为空便利得到内容,然后得到内容,咱们判断,如果它还是文件夹啊,文件夹写错了啊,如果他还是文件夹,那我们继续进行操作,就是继续进行咱说那个递归还是便利,再看它里边有没有其他的内容,如果它不是文件夹,是文件,那咱怎么做得到包路径加类名称部分,就是com后面那个部分,然后得到之后判断文件是否是点卡类型,是的话把斜杠替换成点,把点卡去掉,最终变成这个样子,因为只有这个样才能用到反射,然后最后再判断这类上边到底有没有这个注解,有注解做实例化,没注解不做实例化,实例化之后把对象放到map集合中去,就是咱们创建这个factor,然后放的过程中判断一下当前这个类,如果有接口,让接口class作为没有接口就是自己。
23:01
作为K。以上啊,就是咱们说的一个基本的过程分析,这个咱们先说到这里。
我来说两句