00:00
各位同学大家好,我们继续,那么通过上一讲,我们终于完成了spring循环依赖的。底层源代码的一步一步详细的debug级别的讲解,那么我相信同学们肯定会非常的痛苦,而且你自己在做自己的家庭作业和练习的时候,你会觉得你打着打着你这个断点一定会打飞,这些都正常,不奇怪,但是我只有两个字啊。坚持,那么同学们啊,我们先闲聊两句。那么大家可以看得出。如果你对你的自己的技术有追求,并且你想去大厂,说白了就是想拿月薪25000,年薪30万以上,比方说工作个七八年以后,想混成阿里P7的话,拿到年薪百万有股票的话,那么这些基本功和内功,你是要在日常工作当中和学习当中点点滴滴的逼自己成长,那么现在呢,你不用有任何怀疑,这些我们没有这一讲我们没有讲写过任何一行代码,几乎全是的。
01:07
官网的源代码的第八个详细讲解,给大家清楚认真的解析了什么是循环依赖,什么是spring的三级缓存,以及对象从初始化到属性的填充,一步一步的在spring容器里面怎么从三级缓存。慢慢的逐步,最终全部迁移到一级缓存,在容器池里面,成品池里面,公外暴露了以后提供调用。那么通过这样的学习,也许一瞬间你不会说拿到这个以后你能做出个什么东西,但是你的内功就是需要靠这样点点滴滴的。强迫自己逼出来,正所谓练武不练功,到老一场空,那么下面呢,我们呢,通过上一讲,那么同学们如果可以,请你一定debug断点跟一下,不用你写代码,你只需要用idea debug能够跟得下来,能够。
02:03
参考杨哥的步骤,把三级缓存的构建迁移整明白了,那么这道题目我相信你能够啃下来,那么连spring源代码你就能够有这个耐力和耐心,这么长的源代码你都读得下来,而且能够debug读得懂。恭喜你,那么我认为你成为一个Java高级开发工程师的底子是具备的,所以说杨哥一开始跟大家说过,我不会给你们上语文课,用什么word文档给你总结好一大堆文字,让你去背这个题目,我带着大家刷题,但是我不带着大家背题,毕竟我们是理工科,是玩脑子。尤其搞it,你要想做高薪程序啊,说穿了你要想拿年薪四十万五十万以上,这种毅力,这种钉子精神定在这儿,把这个问题磕死死磕搞透,这个是需要一种坚持和耐力的。那么。一定要跟这些bug,一定要跟这些困难有血战到底的勇气,那么下面呢,同学们。
03:01
如果你的断点打飞了,很正常,不要气馁,不要郁闷,不要觉得啊,怎么这么难,相信我跟着下来,你的内功提升就是这样一次次痛苦当中慢慢的磨砺出来的,正所谓做难事必有所得,接下来如果你还是不行,那么看着杨哥的视,行完了以后,主机。全部第八个断点我都给你总结好了,哪一步哪一步,哪一步哪些类第几行,大家请看我们第一个断点是不是我们的这个第14行,那么请你参考我这个挨个挨个的打一下你。一定要坚持下来,而且一开始我是说过这个是不是困难,我最怕的就是你觉得,哎呀难了,你你讲什么呀,我听不懂了,撂挑子不干了,这个时候,那么你。你的心血。杨哥的付出,咱们的配合是不OK的。教学教学教在学前还是请同学们能够动手练一下,不要觉得老师讲的难就不想学,你听不懂很正常,这是大厂高阶班的对标阿里P6P7这样的层次的程序啊,所以说这种spring源码的阅读能力你是必须要具备的。
04:13
OK,因为到大厂工作,比方你去美团,阿里甚至京东,它里面内部就是用自己封装的框架,可能有时候你为了解决一些故障和一些难题,你需要去阅读他们自己公司内部封装好的框架的源代码,假设你有那个权限的话啊,那么这个时候你平时这种基本功,你连spring的源码都能够阅读下来了,那么你们公司内部写的那些框架,那些中间件,你有什么不能阅读,难道他比spring还牛?不可能,所以说同学们,这个就是我们完全按照。BAT大厂的标准来要求大家,OK,好,那么感谢大家听我啰嗦。说到这儿,真心的希望同学们能够。有一个好的前途,有一个好的前途,早点进大厂。多挣钱。多体面干净的,靠自己的城市经营合法劳动多挣钱,好,那么兄弟们下面熟悉杨哥风格的都知道三板斧理论实操小总结,理论完了,实操嘛,够了吧,全体bug spring源码。
05:17
下面总结一下spring是如何解决循环依赖的,那么这样啊,在总结之前,我们先提前说一嘴啊。现在你。爆出来的spring。循环依赖。这个题目。只讲解了。50%,你可以把它当做是上半场。为什么呢啊,因为限于我们的时间和我们大厂班的要求。还有下,因为这些题目他会问你。为什么一定要用?三级缓存。我用二级可否?
06:02
一级可否?它会更加灵活的变种,题目是需要你对它有更灵活更深刻的掌握,那么好,比如说啊,是否可以。关闭。循环依赖。等等等等。那么另外的下半场的还有围绕着循环依赖的其他题目,欢迎大家来到上硅谷大厂高阶班后续报名以后杨哥再给你讲更狠更难的。那么目前。我们呢,先把手头上的先做好,那么走起,我们总结一下spring是如何解决循环依赖的。那么来,首先。这个三个缓存。然后我们是不是用最简单的一句话,你要用就要去容器里面去获得,这个病默认是不是都是single的单利的,如果能够获得,OK,直接用,不能获得我们怎么样,是不是要创建,在创建的过程当中,挨个挨个的去填充属性,最后。
07:07
完了以后再把它填到我们的池子里面,最终放到一级缓存,从成品暴露给服务调用者去使用。大体而言说,简单一点就是从左到右这四个方法的。这四个过程的一步一步的挨个挨个的完善和最终成型,那么接下来同学们我们来复习一下。首先spring它创建并呢,主要分为两大个步骤,首先先创建原始并对象,比方说我们的A,接着去填充属性和初始化,每次创建之前,他都要先从容器,也就是我们的一级缓冲里面先找找有没有。因为是单列,整个容器只会有一个你,你们家那个鱼缸里面一模一样的鱼是不是只会有一条?当我们创建A这个原始对象的时候,我们发现干嘛没有这个A,然后开始是不是首先把它放到三级缓存,然后完了以后就要接下来叫对A填充A里面所具有的B属性,结果突然发现A是依赖于B的,那么我们再轮回一次,创建A的过程当中发现需要B属性,那么我们就又去创建B,同样的流程,建完B以后发现B也需要填充属性A,它又依赖于A,那么又是一圈同样的流程。
08:24
不一样的是,我们在创建B的时候,已经在三级缓存当中查找到了。头开始我们创建的一个毛坯房一样的一个A,还记不记得原来我们说过在那个三级缓存里面有一个A,两个全是拉姆达表达式,它们两个首先都是在三级缓存里面。所以呢,此时我们不再需要继续创建,用它呢,注入B,完成B类创建以后,那么把B直接从三级放到一级缓存A。还在?二级缓存了,但是这个B已经在三级,从三级缓存跳到一级缓存,变成了成品,所以这个时候A再去完善。
09:04
填充属性的步骤,那么完成剩下的业务逻辑,完成闭环,那么最重要的我们要把这段代码呢给同学们呢?大概做了个总结和抓出来,首先一级缓存没有就去二级找,二级没有再去三级找,三级有的话干嘛?是不是把它移动到二级,我们的A的创建过程是不是就这样。那么整个过程同学们呢,一定一定要注意。Spring解决循环依赖它是靠的病的,什么中间态的这个概念,也就是这个中间态就是指有点类似于放在二级缓存里面的,已经实例化好了,你房子已经买好了,但是是个毛坯房呢,还没装修呢,还没有彻底完整的初始化完成,还没有到一级缓存的单利池里面,它目前是个什么状态,半成品。但是你又不能说这个半成品没有,所以说B就可以引用这个A,是彻彻底底等B完成了,再去完善这个半成品A,让它从二级到一级,那么实例化的过程当中,又是通过构造器A没有创建好,是不可以提前暴露的,所以构造器的循环无法解决,那么spring为了彻底解决单利的循环依赖问题,他不得不使用。
10:17
三级缓存这个概念。AB假设两个互相循环,引用实例A的时候,先把A放到三级缓存里面,接着外位要为A填充属性,发现A有一个属性要依赖B。同样的流程,然后呢,也是实例化以后,将B放入三级缓存,接着去填充属性的时候,又发现B自己呢依赖于A,这个时候从三期缓存中就会查找到早期暴露的A。如果后续也没有加op op代理的话,那么直接将A的原始对象弄给B,完成B的初始化后,再进行属性的填充和初始化,这个时候B完成以后就只剩下完成A的这个动作,那么如果有a op的话,那么就进行a op的处理,获取代理后的对象A注入B,走剩下的流程大致就这么一个,那么由于我们本次讲啊就没有。
11:12
设计a op这些我们没有配那些东东了,所以说呢,大概流程简单版就是上面这个,那么接下来。你在打断点,一方面请参考杨哥的视频,另外一方面请参考我的断点,打在哪,一定要自己动手,再次强调请坚持,做难事必有所得。那么如果你还是不明白,那么第8UG的步骤我也给大家解决了循环下的依赖过程,我们呢,走一圈我们的全部流程,再来反复的回顾这四个方法。走起,首先要创建,哎,那么我们从池子里面想get。并想获得A有到这就结束了,直接要没有怎么办,是不是我杨哥强调过spring底层源码里面只要是小度开头的才是真真正正干活的,那么请看啊,然后呢,尝试从各级缓存里面要获得这个I get single time有没有这个I,没有没有怎么办?
12:06
见。开始创建这个并这个实例,又调方法重载get single,这个时候要创建A,然后我们是不是说过一个叫single factory这么一个参数完了以后呢?请看到第二步是不是create变要创建A,然后一大堆参数,然后create变了以后对应着是不是得到直接用。得不到开始创建create变create并,其实底层就是我们这个do create并这个方法我们到这儿。开始创建并对象,那么创建完了以后填到哪,是不是首先先填到三级缓存a single factory这个里面,完了以后。A现在在三级缓存里面待着了,我们写过一个TV键值,对那个K,就是这个a value是不是一个拉姆的表达式啊,还给大家抓过图,好,那么接下来populate b是不是要对A进行属性的填充,在对A进行属性填充的时候,发现A要依赖B,接着我们就去找B,那么又回到原来那个流产。
13:07
需要哪个,就从容器里面get,能不能get get得到直接用,Get不到干嘛?开始依赖于我们的并工厂去创建,那么还是你看啊,Create b,这是A,这是B,这是b do create,首先是A,再do create create是B。所以说又把这个流程重复一遍,不多啰嗦了,直接到这儿。天道工厂里面开始创建。B,然后发现在也要对B进行属性的填充,那么又轮回过来。这个时候。B需要有A,但是A怎么着,是不是已经先在三级缓存里面了,算是扎了个根,听懂了吗?那么这个时候就可以获得A的早期引用,那么这个时候我们将从容器里面的三级缓存里面先找找有没有A找得到,由于第一步已经添加了缓存,所以这里呢,不带为空,将三级缓存的A移动到什么二级缓存,明白返回A的什么原始对象,然后。
14:11
帮助B完成属性的填充走起。那么接下来。这个B从实例化到初始化,买好B这个房子啊,到开始慢慢装修,然后at single,那么同学们请看这个是不是属性填充,第四个方法是不是ADD single上要填回容器里面了,那么这个B。过来又调用这个方法。并B完成了初始化实例化和初始化买房子,毛坯房到装修完成,B里面装修了A的,然后最后完成A的实例化,那么。以此类推,彻彻底底完成整个流程,打完收工,走完那把上面再进行文字性的总结。我们再带着大家。过一遍给大家讲详细点,请你一定要突破你的源码,能够跟着debug断点打下来,你一定内功,你的基本功才会扎实,功夫才到家,所以说有这十步,我们呢,快快的过一遍,给大家一分钟阅读一下,好。
15:14
那么刚才呢,也给大家一些时间,就是对上面这张图的一种文字性的总结,以对我们最后的一个流程的梳理。读给变找A,然后调用这个方法缓存里面去找。拿得到直接用,拿不到干嘛返回难,完了以后发现这个是为难的话,那么走对应的处理逻辑,是不是要进行方法的重载,参数为就是这个。听到没有的话,我是不是要开始创建,然后并把它填到三级缓存里面,挨个挨个那么这些。我相信通过我们的debug和上面这个图的讲解。节约时间,后面的我就不再带着大家读了,那么最终我们完成了。Spring循环依赖,OK,那么好。大家呢,认认真真的复习一下这个题目,说不定会被考到,OK,好的,那么对于这一关,我们就给大家介绍到这。
我来说两句