化繁去简,梳理IOC核心脉络
- 入口:bean的创建
进入 refresh 方法 -》 preInstantiateSingletons
遍历了 beanDefinitionNames,并根据 beanName 进行了 getBean
doGetBean -》 getSingleton -》 createBean
resolveBeforeInstantiation 为对象创建代理对象
doCreateBean - 》 BeanWrapper createBeanInstance
-》 instantiateBean(beanName, mbd);
-》 instantiate 首先获取了当前这个类的构造器, 通过
BeanUtils.instantiateClass(constructorToUse) 返回实例
-》 ctor.newInstance
实例已经创建了,但是属性值还没有,先判断早期的 bean 暴露出来,如果有循环依赖, 调addSingletonFactory 把bean 加入到 spring 的第三级缓存
-
填充属性,此处解决循环依赖
populateBean 设置属性
循环遍历 BeanPostProcessor , 其中有
AutowiredAnnotationBeanPostProcessor,就是处理我们 @Autowired 注解的类
进入bp.postProcessProperties
里面首先获取了当前类中以 @Autowried 注解的属性,然后开始注入
inject 方法内部,循环遍历需要注入的属性进行注入,
AutowiredFieldElement. inject() 再进入resolveFieldValue
首先调resolveDependency() 处理了依赖关系, 进入doResolveDependency里面调用 descriptor 的 resolveCandidate方法, 就看到了我们非常熟悉的方法了:beanFactory.getBean(beanName) -
接下来循环依赖
先记住三级缓存
一级缓存 singletonObjects 中存放完全初始化好的 bean 的实例。
二级缓存 earlySingletonObjects 中存放早期对象(未完全初始化完成的 bean 实例)。
三级缓存 singletonFactories 中存放 bean 工厂对象。
假设刚刚实例化的是payServicelmpl这个bean,初始化读到属性userservice,然后就开始实例化userservicelmpl这个bean,继续走一遍getbean流程。到populateBean设置属性时,它有个payservice,重复前面的流程到beanFactory.getBean
先进入getSingleton,前面在创建payServicelmpl这个bean时,初始化还没完成,所以从singletonObjects取的是null,但是isSingletonCurrentlyInCreation是true,
allowEarlyReference也是true,就可以到singletonFactories里面取,就呼应了
populateBean前addSingletonFactory这个方法。
然后将它存到二级缓存 earlySingletonObjects 中,并删除三级缓存中的当前 bean
此时,回到 doGetBean 中,这次获取到的 sharedInstance 就不是空了
接下去执行 getObjectForBeanInstance, 如果不是 FactoryBean,这里面直接就返回当前实例 。
再回到 用 AutowiredAnnotationBeanPostProcessor 的 postProcessProperties 方法的地方,现在发现 userServiceImpl 中的 属性已经设置好了,到这边为止,userServiceImpl 的 populateBean 就执行完毕了
然后调用 exposedObject = initializeBean(beanName, exposedObject, mbd); 进行最后的初始化并暴露此 bean
最后,返回已经初始化完成的 bean
然后,一层层退出,最终回到给最初的 payServiceImpl 设置属性的地方
获取到完整的 bean 之后,会将此 bean 实例加入到一级缓存
getSingleton(String beanName, ObjectFactory<?> singletonFactory ) --> addSingleton(beanName, singletonObject);
文章详细阐述了Spring框架中IOC容器创建bean的过程,包括从refresh方法开始,预实例化单例,通过BeanUtils创建实例,处理构造器依赖,解决循环依赖机制,特别是@Autowired注解的处理和属性填充。在这一过程中,涉及到了Spring的三级缓存机制,确保bean的正确初始化和依赖注入。

被折叠的 条评论
为什么被折叠?



