00:00
好,同学们,我们继续。接下来我们呢,就要慢慢的引入我们的spring容器,给大家来说一下。什么叫基于spring容器的循环依赖?好,毕竟刚才也看到了这个是不是IC容器的相关知识,毕竟是spring官网嘛,那么之前都是纯加。编码解决这些问题并演示啊,那接下来走起。来吧,我们这儿呢。AB。可扣的还是最朴素的三个类,现在还没有引入容器呢啊。再看一遍。AB,那么纯编码。大家请看A里面有一个属性B。B。钙的方法,这个是A的无参的构造方法。如果A。创建成功,打出来这么一句话。B也这么回事,B里面有一个属性A。A有s get方法,B的构造方法,打出来这么一句话,那下面。
01:02
大家请看你有A,你有B,里面注AA里面注B,那么大家请看现在是什么纯粹的啊,纯加YC代码再来一遍。A乘高B乘高,没什么好说的,这个过,那接下来同学们。你都明白AB了,我呢就要在这个的基础上引入spring容器,那首先我们为了好讲课,我这儿呢。直接弄了一个。单例和proto原型的先提前说结论。一般我们spring默认都是单利的病,所以呢,你在spring的日常运行过程当中,你很少会看到什么循环依赖报错这种bug。它是支持循环依赖解决的,它不会报错,但是我们的原型prototype这个场景是不支持循环依赖的,它会报错。好,那么同学们,我们呢,先引入spring的容器application X,那么这呢,慢慢的从纯加Y线。
02:06
加上我们的容器,我们的容器呢,很简单,大家请看这就是一个什么OBX的上下文的一个配置。X的配置文件,这个里面有两个B,有两个B,你可以把它当做就是一个spring的一个容器,一个鱼缸里面养了两条鱼,一个叫A,一个叫B,这个是A的定解,但是A里面有个需要有个属性B,它引用自BB里面。第二条它有个属性是A,需要引用A,好说,那接下来我们来看看基于spring容器的测试啊。走起,我相信这两行代码不用我多废话吧,同学们都懂吧?好,那么来看看,这个时候我们正常的运行肯定不会报什么错。AOKOK,没问题吧?貌似好像样,杨哥你讲到这儿,我不管你是加C的纯代码还是加入容器,这不就跟我们平常用的最简单的hello word入门级别的案例吗?没有什么呀,没报什么错呀。
03:03
别着急。你像这么干的时候。如果我这scope你懂的。我们这儿就是写不写这一行代码,是不是没有写的话,默认就是相当于是single安利的容器里面,所以说我们这儿再跑。AB没有任何问题吧,但是如果我们这儿把它改成prototype。同学们。睁大眼睛看好,哎呀,咱们把那个类关了。再跑一次。现在啊,什么都没到,现在都是好的,就把那个容器的这个值。给换了,每次对象都是新的。那么相当于说这个时候同学们请看是不是什么原因引起的病,Currently in creation。Exception,并在正在创建的过程当中挂了,那么同学们请看,并抛出这么一个异常,是不是跟官网吻合了,为什么呀?因为错误的创建一个B,名字叫A的,它要求正在创建的时候它就会容器就。
04:14
懵逼了,他会问主人,这是不是有一个无法解决的循环依赖的这么一种理由,那么这个就是我们循环依赖报错的一种故障现象。OK,这个是需要你现在对spring容器有了解的。那为什么我们改了这么一个pro原形的就不OK呢?那么回到这儿。我们呢,先把正确的结论记着。如果这就是我们新产都是用磁盘容器默认的,它是不会报错。OK的,但是如果你改成这样,存在着A有BB有A的话,它是会报错的,明白这个磁盘容器本身。故障不能说故障,它本身的特性,它的容器现象就存在这么一个,所以说现在大肠考的就是看看你知不知道这块对spring的熟悉程度,好的。
05:05
那么接下来我们循环依赖的异常。那么就告诉。你们的面试官会报这么一个,并在初始化正在创建的时候报这么异常打出来的提示,就这么一个告诉对方。我见过什么是循环依赖?好,那么接下来我们先提前说一下。重要的结论,Spring容器内部是通过三级缓存来解决循环的依赖这个问题,也就是说如果出现循环依赖了,那么建议大家要用single这个方法来解决,你看它才可以。通过嘛,不报错,那么接下来就是常见的高频考点,你知道spring的循环依赖吗?你知道spring内部的三级缓存吗?那么这儿来说一下,把这个类希望同学们呢,默认的single的b register这个类呢,给我背下来,名字你告诉官,告诉面试官,你看过官网,待会儿也确实看过官网,看过源码,待会我带着大家看嘛,是吧。
06:04
记账,这是第一个知识点,第二个知识点直接说所谓的三级缓存,其实就是储存容器内部用来解决循环依赖这种问题的三个map。走起。来,同学们请看。这个就叫default这么一个类,OK或者呢啊,我们呢,直接啊,先带着大家看一下源码,然后我们再看我们老图笔记,那么找到我们的这儿。来,同学们。我们呢,直接点开这个就是日产。比面试当中会问你的。大家请看。名字叫这个特别长,我就不读了。何为三级缓存?就是这的三个map,请大家看它们三个有什么区别和不一样?OK吗?好。请看map,你看它是cash of single object,那么这个挺好,看看map这个啊,叫一级缓存。
07:09
然后呢,下面这个叫厄尔,就是过早暴露出去的,这个叫二级缓存,最后这个叫三级缓存,所以说它的顺序不是123,它的顺序是一。三。二明白了吗?好,这是第一个知识点。其中一个是康哈西,另外两个是哈希。第二个知识点,请看它的KV键值队。一级缓存和二级缓存,二级就是earlier这个啊,它们两个呢,都叫object,这个value,唯独是三级缓存,第三个single factor这个它传了一个object对象进去,这个是它们三个的显著区别和不同,那么回到我们的脑图笔记。我们再打来看一下啊,这三个类叫这个。
08:03
一级缓存是看卡哈。二级缓存是带着earlier这个三级缓存,只有它是什么?传一个工厂进去,Object factor这一个,那么在这也给大家做好了一个。说明,所以一级缓存,也就是我们所说的spring容器,就叫单利池,一般我们的single的那些对象都放在这个map。存放已经经历了完整生命周期的并对象说穿了就是那些产品,Supreme弄出来我们都明白,Supreme讲过,他就是个大的工厂,这个工厂已经生产好产品了,你可以直接从厂家拿货。出产了。这种东东放在一级缓存里面,那么二级缓存是带着这个early这个了,它是存放早期暴露出来的病对象病的生命周期还没结束,就是属性还未填充完整的,你可以把它当做这个是半半成品的,听懂了吧,那么第三一个。
09:00
注意这个参数叫object factory的存放可以生成的工厂的,那么这个呢,就是准备来构建对象的,那么所以说这个。放成品这个放半成品这个是准备生产的,所以说呢,这个三级缓存它各有用处。来。直接先说结论。只有单立的病也是single的时候,配置成single的时候,就是我们这儿啊。配置成single的时候听懂了吧,那么我们呢,会通过三级缓存spring容器提前暴露来解决循环依赖的问题,就是循环依赖这种现象存在着,官网上也说了,盘容器底层是在单利病的前提下,通过三级缓存来给你解决了,而如果是非单立的病,什么叫非单列?就是我们这的。Pro相当于每次一个,那它就没有办,每次都就说明没有办法放在缓存里面,没有办法用spring容器的三级缓存,所以说每次从容器中获取的都是一个全新的对象,就会重新创建,重新创建的还需要放缓存吗?那么三级缓存里面就都没有新建的这个东西它找不到,所以说非单立的病。
10:13
没有放在缓存里面,不会跟3G缓缓存发生关系,所以说就会报我们刚才的bug,哪个是不是就是我们的这个东东啊。好,那么所以说这儿请大家一定要注意。Spring内部是通过三级缓三级缓存来解决循环依赖的这种现象,好,那么这一章我们就讲到这儿,下一章给他深度解析源码。
我来说两句