简单理解spring源码如何加载bean,实例化,初始化和解决循环依赖
spring容器启动
调用了构造方法的refresh()方法
在倒数第二个方法 里面做了准备工作和实例化懒加载的单例bean
最后一个方法是实例化懒加载的单例bean
首先,spring加载bean大致分为4步,getBean,doGetBean,createBean,doCreateBean。
这里做完判断以后就会去getBean
进去以后就会看见方法doGetBean
点进去
会在单例池中get这个bean 也就是一级缓存
方法实现:
第一次get为空,并且没有被暴露
返回null
开始创建bean 调用这个方法 key是beanName value是一个lamda表达式 但并没有被执行
进来发现是先在一级缓存中get这个bean 如果为null 下边掉用了getObject才是调用了createBean
do开头的方法是做事情的方法 开始创建bean
这个方法用来实例化bean
进来以后spring会推断最合适的构造方法 我这个只是测试,调用了最简单的无惨构造
到这里以后就完成了bean的实例化
然后跳出来
到这里以后就会把这个bean放入到三级缓存中 这里传入的也是个lamda表达式 也是没有被执行
这个lamda表达式是用来解决aop代理对象的问题,如果使用了代理对象就操作这个方法完成代理,这个我还不太明白
然后开始初始化这个bean 进行依赖注入
发现有一个属性
然后开始
解析一些必要的属性值吧应该 我猜的
这是一个还没准备好的类型
然后getBean 要给A的B属性装配
又到doGetBean方法 循环一次
单例池也是获取不到B 会创建一次B
在实例化B后会给B的A属性填充 会开始getBean 而A是已经暴露在了三级缓存中,A还是个半成品,但已经可以让B拿到然后初始化了
这个是getBean的逻辑 首先从一级缓存里拿,然后是二级三级
拿到这个bean B就完成了属性的依赖注入 然后开始初始化这个bean
先执行判断这个bean有没有实现aware接口 实现了就调用
beanPostProcessors 的postProcessBeforeInitialization方法
执行initmethod方法
beanPostPercessors的postProcessAfterInitialization
然后B就完成了初始化
然后把B放到一级缓存中
然后A也能拿到B的bean
总结一下:spring解决循环依赖主要是将实例化和初始化分开,实例化完成后加入到三级缓存中,使得依赖的bean可以get到他。
bean的加载过程就是首先先在单例池get这个Bean,调用doGetBean方法,如果没有,会开始创建Bean,doCreateBean,实例化完成后,开始属性的注入,如果依赖其他bean,流程一样,最后属性装配完成后,开始初始化,调用aware接口,beanPostPorssors的before方法,initMethod,beanPostPorssors的after方法,完成初始化
后续会继续加油!!!