时间:2022-08-05 11:43:09 | 栏目:JAVA代码 | 点击:次
前文已经讲述了Spring BeanFactory 与 FactoryBean 的区别详情,在本文中将继续讲解 Bean 的创建和初始化,在这个环节中将会涉及到 Bean 的创建、初始化和循环依赖内容。
在前文中已经讲述了 Spring 容器启动的核心方法 refresh,关于 Bean 的创建和初始化方法都是在 finishBeanFactoryInitialization()
中进行处理,在这个阶段就是处理所有剩余的非懒加载的单例对象。
在该方法中,调用 preInstantiateSingletons()
进行 Bean 的所有单实例 bean。 在这个过程中,会获取容器中的所有 Bean, 依次进行初始化和创建对象。获取所有的 Bean 定义信息 beanDefinitionNames
。在处理 Bean 时需要判断 Bean 定义信息是不是抽象的,单例,和懒加载。其核心方法为 getBean , 也许大家都知道在获取 Bean 的过程中,会经历 getBean -> doGetBean -> createBean -> doCreateBean
方法调用链,在 Spring 源码中, doXXX 的方法都是实际业务的方法,在 doCreateBean
方法中,createBeanInstance
方法是真实创建 Bean 对象的方法,在 Spring 中,都是采用反射的方法来创建对象的。这些核心的方法都是在 AbstractAutowireCapableBeanFactory
中实现,下图便是 doCreateBean 方法,其中的核心操作有三个: createBeanInstance 、populateBean、initializeBean
。
createBeanInstance
是创建 Bean 对象的方法,这里最终调用的是 instantiateBean
方法,最终的调用栈如下:
AbstractAutowireCapableBeanFactory.instantiate -> SimpleInstantiationStrategy.instantiate -> BeanUtils.instantiateClass -> ctor.newInstance
populateBean
是设置 Bean 属性的方法,如下图所示 autowireByName
和 autowireByType
两个方法即是自动注入的方法,以 autowireByName 为例,获取属性是以 getBean 的方式从 IOC 容器中获取对应的 Bean。
初始化 Bean 是在实例化之后的操作,在初始化之前和之后便是 BeanPostProcessor
的操作,初始化的操作便是 invokeInitMethods
的初始化方法。
# 在初始化之前和之后执行 applyBeanPostProcessorsBeforeInitialization applyBeanPostProcessorsAfterInitialization
初始化 Bean 的操作
初始化之前和之后的操作方法:
循环依赖是绕不开的话题,循环依赖的问题具体的表现形式如下:
在讲循环依赖如何结果之前,还是涉及到 Bean 是如何创建的,如下图所示的过程就是解决循环依赖的过程。
Abstra ctAutowireCapableBeanFactory.doCreateBean
方法核心内容如下:获取单例 Bean 的方法:
初始化的方法如下所示:
通过以上的三个步骤,就实现了循环依赖的问题解决,也完成了 Bean 对象的创建过程。
为什么要使用三级缓存呢,说到底是要解决以下问题:
文中主要讲述了 Spring
容器中 Bean
的创建过程已经主要的方法,另外也着重分析了循环依赖的问题.