getBean的粗略分步
- 三个步骤
- createBeanInstance:实例化
- populateBean:依赖处理
- initializeBean:初始化
处理方式
- 非构造器
- 在缓存那个地方,有三级缓存架构
- 一级缓存:singletonObjects
- 二级缓存:earlySingletonObjects
- 三级缓存:singletonFactories
- 在postProcessMergedBeanDefinition之后,populateBean之前,有一个操作DefaultSingletonBeanRegistry.addSingletonFactory,也就是说加入三级缓存
- 案例:Bean1依赖Bean2,Bean2依赖Bean1;先获取Bean1
- Bean1在三个缓存中都找不到,创建Bean1,加入三级缓存;populateBean的时候,依赖Bean2,所以先去获取Bean2
- Bean2在三个缓存中都找不到,创建Bean2,加入三级缓存;populateBean的时候,依赖Bean1,所以又去获取Bean1
- 首先,一级缓存中没有,isSingletonCurrentlyInCreation为true,进入同步块(这儿采用一级缓存作为同步对象)
- 然后在二级缓存中查找下Bean1,也没有
- allowEarlyReference,这个变量什么情况下会变成false???
- 查找三级缓存,找到了singletonFactory(AbstractAutowireCapableBeanFactory),调用singletonFactory.getObject,得到了不完整的Bean1,加入二级缓存,从三级缓存中移除
- 那么这个时候,Bean2的依赖注入就可以完成了,虽然里面的Bean1是个不完整的;Bean2先走完getBean
- 回到Bean1的populateBean中,Bean1的getBean也走完了
- 这个时候:一级缓存有Bean1和Bean2;二级缓存没有,二级缓存中是什么时候被移除的呢
- AbstractBeanfactory的mbd.isSingleton()下面的getSingleton(beanName, new ObjectFactory<Object>()那里
- 在缓存那个地方,有三级缓存架构
- 构造器
- Bean1在构造器中依赖Bean2,Bean2也在构造器中依赖Bean1,跪
- Bean1在构造器中依赖Bean2,Bean2在属性依赖Bean1,不会有问题的
- Bean1在获取构造器参数的时候,会去调用getBean(Bean2),原理上和populateBean是一致的,只是时间点有区别,在createBeanInstance里面
- prototype也能处理循环依赖吗?how?
网友评论