今年的铜三铁四到了,给大家写几篇面试题解析
A依赖于B
B依赖于A
对应的xml文件
关系图
spring使用了三级缓存来解决依赖,把bean的实例化和初始化分开存放
一级缓存singletonObjects:存放初始化完成后的bean
二级缓存earlySingletonObjects:存放实例化完成后的bean
三级缓存singletonFactories:解决有aop代理的bean的循环依赖问题
准备debug环境:
进入ClassPathXmlApplicationContext的构造方法
finishBeanFactoryInitialization方法
preInstantiateSingletons方法
getBean方法
doGetBean方法
getSingleton方法
去一级缓存里面拿a
返回的singletonObject为空
返回的a为空,一级缓存里面没有a对象
getSingleton方法
调用lambda方法
createBean方法
doCreateBean方法,实例化a对象
getWrappedInstance方法,完成a的创建,底层使用反射创建对象
addSingletonFactory方法
向三级缓存加a对象
此时缓存情况,a对象b属性为null
populateBean方法
applyPropertyValues方法,填充b属性
resolveValueIfNecessary方法
resolveReference方法,处理b属性
getBean方法,又回到了这个方法
getSingleton方法
此时没有缓存中没有b对象
createBean方法,创建b对象
到目前为止,a和b对象的情况为
addSingletonFactory方法
此时缓存里面的情况为
populateBean方法,给b对象里面的a属性填充值
applyPropertyValues方法
又回到了上面的方法applyPropertyValues,第二次出现,又回到了getSingleton方法,从一级缓存里面找a对象
一级找不到
二级找不到
三级找到了
拿到了半成品的a
往二级缓存添加a对象,三级缓存删除a对象
此时的缓存情况,三级缓存移除a,二级缓存添加a
从三级级缓存拿取到a半成品
将a的值赋值给b
此时a和b的情况
addSingleton方法
此时的b已经是成品了,所以一级缓存添加b,二三级缓存删除b
现在的缓存情况
一级缓存已经有了b对象成品,所以只要给对象a赋值就行了
addSingleton方法
一级缓存添加a,二三级缓存删除a
我们后面从ioc容器中拿取a对象都是从一级缓存里面直接拿a的成品