简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖

简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖

简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
spring容器启动

简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
调用了构造方法的refresh()方法

简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
在倒数第二个方法 里面做了准备工作和实例化懒加载的单例bean
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
最后一个方法是实例化懒加载的单例bean

首先,spring加载bean大致分为4步,getBean,doGetBean,createBean,doCreateBean。
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
这里做完判断以后就会去getBean
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
进去以后就会看见方法doGetBean

点进去

简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖

会在单例池中get这个bean 也就是一级缓存

方法实现:简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
第一次get为空,并且没有被暴露
返回null

简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
开始创建bean 调用这个方法 key是beanName value是一个lamda表达式 但并没有被执行
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
进来发现是先在一级缓存中get这个bean 如果为null 下边掉用了getObject才是调用了createBean

简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
do开头的方法是做事情的方法 开始创建bean

简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
这个方法用来实例化bean
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
进来以后spring会推断最合适的构造方法 我这个只是测试,调用了最简单的无惨构造
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
到这里以后就完成了bean的实例化
然后跳出来

简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
到这里以后就会把这个bean放入到三级缓存中 这里传入的也是个lamda表达式 也是没有被执行
这个lamda表达式是用来解决aop代理对象的问题,如果使用了代理对象就操作这个方法完成代理,这个我还不太明白
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
然后开始初始化这个bean 进行依赖注入

简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
发现有一个属性
然后开始
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
解析一些必要的属性值吧应该 我猜的
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
这是一个还没准备好的类型
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
然后getBean 要给A的B属性装配
又到doGetBean方法 循环一次

单例池也是获取不到B 会创建一次B
在实例化B后会给B的A属性填充 会开始getBean 而A是已经暴露在了三级缓存中,A还是个半成品,但已经可以让B拿到然后初始化了
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
这个是getBean的逻辑 首先从一级缓存里拿,然后是二级三级
拿到这个bean B就完成了属性的依赖注入 然后开始初始化这个bean
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
先执行判断这个bean有没有实现aware接口 实现了就调用
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖

beanPostProcessors 的postProcessBeforeInitialization方法
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
执行initmethod方法
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
beanPostPercessors的postProcessAfterInitialization
然后B就完成了初始化
简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
然后把B放到一级缓存中
然后A也能拿到B的bean

总结一下:spring解决循环依赖主要是将实例化和初始化分开,实例化完成后加入到三级缓存中,使得依赖的bean可以get到他。
bean的加载过程就是首先先在单例池get这个Bean,调用doGetBean方法,如果没有,会开始创建Bean,doCreateBean,实例化完成后,开始属性的注入,如果依赖其他bean,流程一样,最后属性装配完成后,开始初始化,调用aware接口,beanPostPorssors的before方法,initMethod,beanPostPorssors的after方法,完成初始化
后续会继续加油!!!