Spring 源码深度解析(第 2 版)读书笔记(四)Bean的加载流程以及循环依赖的解决

进入方法内部,先看整个方法包含了哪些重要方法:

整个方法看完了,接着进入其中比较重要的方法看看:

  第一个getSingleton方法,也就是尝试从缓存中拿

 

  第二个方法:将拿到的bean看看是不是FactoryBean,如果是,那么返回的就是通过getObject方法返回的bean

会在判断是否单例之后,调用doGetObjectFromFactoryBean方法最后拿到bean

spring的惯例,都会在bean创建前后加入后置处理器,提高框架的扩展性

回到外层方法,看过FactoryBean的创建过程之后,接着看bean 的创建过程,第二个getSingleton方法:

 

先看看方法整体:

 

然后看看重要方法,SingletonFactory.getObject方法实际调用的createBean方法:

createBean方法中的resolveBeforeInstantiation方法

因为代理创建的对象就会直接返回了,所以初始化的后置方法在这里会被调用

方法回到外层,进入doCreateBean方法:

整个方法看完,就先进入第一个方法,也就是bean实例的创建方法:

 

构造方法分成两种,一种是有参构造,一种是无参构造,先看第一种:

有参构造的大部分时间花在匹配构造函数和参数上了,现在看看无参构造,相对简单很多:

在创建完bean之后,需要为其属性赋值,初始化等工作:

就算不使用@Autoware,其实到最后还是会在下面这个方法里面,给自动注入属性中

其实解析就是在拿到属性依赖的bean的名字然后去缓存拿或者创建bean

从这里开始,跟着走一圈看看循环依赖是怎么解决的,A-》B-》C-》A

在方法中,其实解决问题的关键是从一开始创建A就埋下伏笔,在创建A之前,会调用方法 1、beforeSingletonCreation(...)会将A的状态设置成SingletonCurrentlyInCreation是true,说明正在创建;然后在创建了A之后,马上调用2、addSingletonFactory(...)将A放进三级缓存中,也就是A只是个半成品;B、C都会经历这段过程,然后在C需要A的时候,那么在一开始的第一个getSingleton方法中,不再是返回null,而是在三级缓存中找到了半成品A,然后C就可以继续属性赋值然后初始化,返回一个完整的C,方法栈开始弹出,回到B的属性赋值上,这时候B拿到了完整的C,然后B也得以继续属性赋值和初始化,返回完整的B,重复上述步骤,回到A,拿到了完整的B,接着赋值和初始化,A创建完成,返回的是完整的A,至此,循环依赖解决了,不过也可以从这看出,如果DI是通过构造器的,或者bean是原型的,那么循环依赖将不能被解决,从而会报错。

 

一开始看源码会很懵逼,所以都是粗略看,不过在spring的使用上越来越熟练的时候,再看源码就会思路比较清晰,这次把bean的生命周期都和循环依赖看懂了部分,还是有所进步的,文中结合书中的一些看不懂的特殊的方法记录了一下,可能解释有误,请大家指出,谢谢。

==================================2021.1.11=====================================================

上文的@Autowire改成@Autowired才对

posted @   huang1993  阅读(137)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示