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进行转换
好啦,以上就是主要的几点,如果想详细学习,建议读源码,读源码,读源码