bean的加载过程是一个复杂的过程,doGetBean()源码很长,这里只是将重点加载步骤列举出来,方便以后复习,初次学习的小伙伴也可以按照这个步骤,细细品读源码.

Bean加载过程

1.转换对应beanName

传入的name可能是bean的name,也可能是FactoryBean

注:通过getBean(String BeanName)获取到的Bean对象并不是FactoryBean的实现类对象,而是这个实现类中的getObject()方法返回的对象。要想获取FactoryBean的实现类,就要getBean(&BeanName),在BeanName之前加上&。

 

2.尝试从缓存中加载单例

对于scope为singleton的bean,在一个容器中只会被创建一次,所以加载一个单例类首先在缓存中获取,如果缓存中没有在到singletonFactories中加载,如果bean中存在依赖注入,就有可能出现循环依赖.

避免循环依赖方法:不等bean加载完成,就将创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建时依赖上一个bean,就可以直接使用ObjectFactory

 

3.bean的实例化

从缓存中得到的bean是最原始的状态,而我们经常需要的是工厂bean中定义的bean-factory方法返回的bean,而getObjectForBeanInstance就是完成这个工作的

 

4.原型模式的依赖检查

当A还没创建完时,由于B的创建再次返回创建A,会造成循环依赖,所以当原型依赖检查结果为true时,抛出异常

 

5.检测parentBeanFactory

当前加载的xml配置文件中不包含beanName,就只能到parentBeanFactory中加载,但是如果parentBeanFactory为null,无论xml是否包含beanName,都不会到parentBeanFactory中加载

 

6.将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition

XML中读取的Bean信息都是存储到GernericBeanDefinition中,但是后续Bean的处理都是在RootBeanDefinition中,所以这里需要做一个转换

 

7.寻找依赖

初始化某一个类时,会先初始化这个bean的依赖

 

8.针对不同的scope进行bean的创建

需要针对不同的scope对bean进行创建

 

9.类型转换

如果传入的参数requiredType与bean类型相同则不需要进行类型转换,如果不同,还需要对bean进行转换

 

好啦,以上就是主要的几点,如果想详细学习,建议读源码,读源码,读源码