spring部分源码分析+循环依赖的问题
2021-12-03 11:49:41 0 举报
spring部分源码分析+循环依赖的问题
作者其他创作
大纲/内容
只是完成堆空间的开辟,并没有设置属性值
总结
refresh()
getBean()
其次找到k:av:b@1157
直接赋值
先查一级缓存,在查找二级缓存,在查找三级缓存
一级缓存三级缓存二级缓存
finishBeanFactoryInitialization(beanFactory)beanFactory.preInstantiateSingletons();
是否能找到b?
A
4、初始化B
spring循环依赖的问题
2、初始化A
是
半成品
5、去spring容器查找a
1、加载了配置文件之后,开始按顺序构建两个bean。2、构建A的时候,将实例化和初始化分开,初始化赋值的时候发现需要b对象的3、去spring容器中查找没有发现b对象的存在(注意:在spring中所有的对象都是先查找,有则直接用,无则创建使用,因为spring中的bean默认都是单例模式)4、如果没有找到的话就得去实例化,初始化b5、而b初始化的时候需要a对象,去找的时候会调用一个lambda表达式,()->getEarlyBeanReference(String beanName),这个选项会存到三级缓存中6、根据k去三级缓存中拿到已经实例化好的A对象的半成品放置到二级缓存中,并且把三级缓存中的数据remove7、然后完成A对象的初始化8、此时A对象的bean就完成了构建,注意此时找到的是A对象的属性b。这之后会把二三级缓存中的值remove掉9、然后再去,走后续流程,去初始化B,初始化B需要a对象,这样去查spring容器,发现一级缓存中已经有了,所以,直接赋值就OK
三级缓存
6、半成品
B
k:av:A@1157
去spring容器中查找b对象
都会被remove掉
首先找到k:bv:b@2152
否
3、实例化B
A类里面有一个B属性,B类里面有一个A属性,
doGetBean()
AbstractApplicationContext类中加载配置文件以后,会有一个refresh()方法
createBean()
doCreateBean()
创建循环依赖bean的过程
去spring容器中查找a对象
1、三级缓存解决循环依赖问题的关键是什么?为什么通过提前暴露对象能解决?实例化和初始化分开操作,在中间过程中给其他对象赋值的时候,并不是一个完整对象,而是把半成品对象赋值给了其他对象2、如果只使用一级缓存能不能解决问题?不能。在整个处理过程中,缓存中放的是半成品和成品对象,如果只有一级缓存,那么成品和半成品都会放到一级缓存中,有可能在获取过程中获取到半成品对象,此时半成品对象是无法使用的,不能直接进行相关的处理,因此要把半成品和成品的存放空间分割开来。3、只使用二级缓存行不行?为什么需要三级缓存?如果我能保证所有的bean对象都不去调用getEarlyBeanReference此方式,使用二级缓存可以吗?是的,如果保证所有的bean对象都不调用此方法,就可以只使用二级缓存!!!使用三级缓存的本质在于解决aop代理问题!!!!4、如果某个bean对象代理对象,那么会不会创建普通的bean对象?会,必须会5、为什么使用了三级缓存就可以解决这个问题?当一个对象需要被代理的时候,在整个创建过程中是包含两个对象吧。一个是普通对象,一个代理生成的对象,bean默认都是单例,那么我在整个生命周期的处理环节中,一个beanname能对应两个对象吗?不能,既然不能的话,保证我在使用的时候加一层判断,判断一下是否需要进行代理的处理。6我怎么知道你什么时候使用呢?因为不知道什么时候回调用,所以通过一个匿名内部类的方式,在使用的时候直接对普通对象进行覆盖操作,保证全局唯一!!!
7、找到了
k:av:lambda
二级缓存
是否能找到a?
refresh方法里面调用了13个方法进行一系列的准备工作以及创建bean
开始创建bean
一级缓存
k:bv:lambda
8、将真实的值放到一级缓存中
1、实例化A
0 条评论
下一页