我们从 TestChangeMethod t = (TestChangeMethod) ct.getBean("A");
开始分析。
首先我们要知道 getBean
方法是哪个类中的。下面给出其类图。
这里我们看 AbstractBeanFactory
中是如何实现该方法的,该类是org.springframework.beans.factory.support;
包中的类。
一、bean
的加载
对于加载过程中所涉及的步骤大致如下:
-
【步骤一】转化对应的
beanName
- 获取很多人不理解转换对应的
beanName
是什么意思,传入的参数name
不就是beanName
吗? 其实不是,这里传入的参数可能是别名,也可能是FactoryBean
,所以需要进行一系列的解析,这些解析内容包括如下内容。 - 去除
FactoryBean
的修饰符,也就是如果name = "&aa
",那么会首先去除 & 而使name = "aa"
。 - 取指定
alias
所表示的最终beanName
,例如别名A
指向名称为B
的bean
则返回B
;若别名A
指向别名B
,别名B
又指向名称为C
的bean
则返回C
。
- 获取很多人不理解转换对应的
-
【步骤二】尝试从缓存中加载单例
- 单例在
Spring
的同一个容器内只会被创建一次,后续再获取bean
,就直接从单例缓存中获取了。当然这里也只是尝试加载,首先尝试从缓存中加载, 如果加载不成功则再次尝试从singletonFactories
中加载。因为在创建单例bean
的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,在Spring
中创建bean
的原则是不等bean
创建完成就会将创建bean
的ObjectFactory
提早曝光加入到缓存中,一旦下一个bean
创建时候需要依赖上一个bean
则直接使用ObjectFactory
。
- 单例在
-
【步骤三】
Bean
的实例化- 如果从缓存中得到了
bean
的原始状态,则需要对bean
进行实例化。这里有必要强调一下,缓存中记录的只是最原始的bean
状态,并不一定是我们最终想要的bean
。举个栗子,假如我们需要对工厂bean
进行处理,那么这里得到的其实是工厂bean
的初始状态,但是我们真正需要的是工厂bean
中定义的factory-method
方法中返回的bean
,而getObjectForBeanInstance
就是完成这个工作的。
- 如果从缓存中得到了
-
【步骤四】原型模式的依赖检查
- 只有在单例情况下才会尝试解决循环依赖。如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对B的创建再次返回创建A,造成循环依赖。
-
【步骤五】检查
parentBeanFactory
- 如果缓存中没有数据的话直接转到父类工厂上去加载。
-
【步骤六】将存储
XML
配置文件的GernericBeanDefinition
转换为RootBeanDefinition
- 因为从
XML
配置文件中读取到的Bean
信息是存储在GernericBeanDefinition
中的,但是所有的bean
后续处理都是针对于RootBeanDefinition
的,所以这里需要进行一个转换,转换的同时如果父类bean
不为空的话,则会一并合并父类的属性。
- 因为从
-
【步骤七】寻找依赖
- 因为
bean
的初始化过程中很可能会用到某些属性,而某些属性很可能是动态配置的,并且配置成依赖于其他的bean
,那么这个时候就有必要先加载依赖的bean
,所以,在Spring
的加载顺序中,在初始化某一个bean
的时候首先会初始化这个bean
所对应的依赖。
- 因为
-
【步骤八】针对不同的
scope
进行bean
的创建- 我们都知道,在
Spring
中存在着不同的scope
,其中默认的是singleton
,但是还有些其他的配置注入prototype
、request
之类的。在这个步骤中,Spring
会根据不同的配置进行不同的初始化策略。
- 我们都知道,在
-
【步骤九】类型转换
二、FactoryBean
与 BeanFactory
1. FactoryBean
接口
一般情况下,Spring
通过反射机制利用 bean
的 class
属性指定实现类来实例化 bean
。在某些情况下,实力化 bean
过程比较复杂,如果按照传统的方式,则需要在<bean>
中提供大量的配置信息,配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。
FactoryBean
接口对于 Spring
框架来说占有重要的地位,Spring
自身就提供了 70 多个 FactoryBean
的实现。它们隐藏了实例化一些复杂bean
的细节,给上层应用带来了便利。
FactoryBean
接口的实现类
2. BeanFactory
BeanFactory
是 IOC
最基本的容器,负责生产与管理 bean
,它为其他具体的IOC
容器提供了最基本的规范,如:DefaultListableBeanFactory
、XMLBeanFactory