BeanFactory是spring的核心,我们都知道可以从BeanFactory中获取到指定的bean(通过名字或者Class),同时我们也会很好奇,bean是怎么被加载到BeanFactory里面的呢?Spring又给我们留了哪些后门能够插手这个加载过程呢?带着这些疑问,我们通过源码一步一步来分析。
首先我们看一下BeanFactory的一个简单的UML图,并对其中几个进行简单分析,这样有助于理解

1、BeanFactory
这是最顶层的接口,它定义了工厂类最核心的方法(可以想想工厂模式,定义一个获取产品的接口)

2、HierarchicalBeanFactory
BeanFactory的直接子接口,表示Bean是有继承关系的,也就是Bean可能有父Bean

3、ListableBeanFactory
BeanFactory的又一个直接子接口,表示这些bean可列表化(可以简单理解为增加了一些接口,可以根据不同的条件来查询bean或者bean的信息)

4、AutowireCapableBeanFactory
BeanFactory的直接子接口,定义bean的自动装配规则(bean创建,属性设置,依赖注入,各种拦截器等)。

通过分析这4个接口,我们能够猜到BeanFactory创建bean真正的类应该是AutowireCapableBeanFactory的子类。
没错,Spring加载Bean的位置确实是AutowireCapableBeanFactory的直接子类AbstractAutowireCapableBeanFactory。接下来我们一步一步来分析AbstractAutowireCapableBeanFactory的createBean方法。
5、AbstractAutowireCapableBeanFactory
实现了bean的创建。现在我们来分析一下他的创建的过程。

可以看出此方法并没有真正创建Bean,我们接着往下看createBean

从源码中可以看出此方法定义了bean创建的步骤:
第一步:先确保bean的Class能被解析
第二步:在实例化bean之前,给了一个钩子(InstantiationAwareBeanPostProcessor),允许我们在钩子中直接返回一个我们创建的bean或者代理,这样,Spring就不会继续往下执行,也就不会在创建bean

第三步:调用doCreateBean,进行bean的实例化,以及后续加工处理。
接着我们继续看doCreateBean方法:



解释一下主要的创建流程:
第一步:根据情况实例化bean
a:如果Bean配置了FactoryMethod,那么使用FactoryMethod进行实例化
b:如果Bean在次之前已经解析出了实例化的构造函数或者FactoryMethod,那么根据情况使用构造函数或者FactoryMethod进行实例化
c:如果能够确定是否指定了构造函数,那么使用确定的构造函数进行实例化
d:如果都没有,那么直接使用默认构造函数(即无参构造函数)进行实例化
(真正实例化bean使用了策略模式,会根据bean的信息选择不同的实例化策略,后面详细介绍)

第二步:Spring又提供了一个钩子(MergedBeanDefinitionPostProcessor),这是用于合并bean定义的后处理器。这么说肯定一脸懵,完全不知道有什么用。
举个例子:我们都知道Bean中可以使用@Autowired注解来配置另外一个Bean,Spring解析Autowired注解的时机就是此时此刻,以便下一步进行属性填充(或者说注入)
(MergedBeanDefinitionPostProcessor这个接口对@Autowired和@Value的支持起到了至关重要的作用,当某个bean在实例化后就会调到所有的实现了MergedBeanDefinitionPostProcessor接口的实例。)
例如:
CommonAnnotationBeanPostProcessor这个处理器用来解析类中使用的@Resource注解AutowiredAnnotationBeanPostProcessor这个处理器用来解析类中使用的@Autowired注解
(注意这些处理器只是用来解析类使用的这些注解,并不会直接注入对应的值)

第三步:填充bean的属性、依赖等
这个过程也涉及很多流程,但是最终就是Spring会在这个步骤中将bean对应的依赖进行设置
第四步:对bean进行初始化
初始化我们不要和前面的实例化混淆了。初始化指的是当我们的bean实例化之后,有可能需要做一些初始化工作(比如:预加载数据)。接下来我们分析一下Spring对初始化做了哪些操作。

a、调用三类Bean的对应方法,他们分别是BeanNameAware、BeanClassLoaderAware、BeanFactoryAware,我们分别可以获得bean的名字、bean的Class加载器、bean的创建工厂。其中BeanFactoryAware是我们常用的,我们的BeanUtil通过实现它,然后在其他服务中可以通过BeanUtil获取BeanFactory,从而在程序运行中获取其中的Bean

b、初始化前的钩子,即:调用BeanPostProcessor的postProcessBeforeInitialization方法

c、调用Bean的初始化方法
此处我们要注意:
如果Bean实现了InitializingBean,那么Spring就会在此刻调用它的afterPropertiesSet()方法
如果Bean指定了初始化方法,那么Spring会调用这个方法

d、初始化后的钩子,即:调用BeanPostProcessor的postProcessAfterInitialization方法

至此,Spring创建Bean的流程基本结束。
