Spring源码学习(三):finishBeanFactoryInitialization
免责声明
本人还处于学习阶段,如果内容中存在错误请见谅,欢迎大家指出错误!!!
写在前面
beanFactory在经过一系列配置后可以开始真正的加载Bean,从这篇开始主要是讲述Bean的实例化过程。
1.finishBeanFactoryInitialization干了什么
下面是finishBeanFactoryInitialization方法的实现,前面进行了一些配置,核心部分其实在preInstantiateSingletons里面。需要注意的是调用了freezeConfiguration方法,该方法会冻结Bean定义,但是之前讲过BeanFactoryPostProcessor可以修改bBean定义,因此BeanFactoryPostProcessor的方法回调会在freezeConfiguration之前。

2. preInstantiateSingletons干了什么
preInstantiateSingletons里面主要处理了FactoryBean、SmartFactory和普通的Bean,这三者实例化的时机略有区别,因此做了对应的处理。
此外,在初始化完成所有Bean之后,该方法还会对实现了SmartInitializingSingleton接口的Bean进行方法回调,可以看到这个方法回调的时机算比较晚的了,在BeanPostProcessor之后。
关于实例化Bean的逻辑还要进去getBean方法。


3. getBean方法做了什么
首先会调用父类AbstractBeanFactory的doGetBean方法。该方法内部其实也并未涉及Bean的初始化,主要是针对父容器、原型Bean、单例Bean等做了相应的处理。


getObjectForBeanInstance方法其实是处理FactoryBean这种特殊情况:

我们继续看doGetBean的逻辑:


有关初始化Bean的核心逻辑还需要继续深入到createBean方法中。
Spring有个小特点,往往会将主要逻辑写在do+方法名中,因此还得去doCreateBean中。

4.createBean做了什么

4.1 createBean
按照Spring命名的特点,真正的逻辑应该在doCreateBean中,我们先看看createBean:

4.1.1 resolveBeforeInstantiation干了什么


如果我们走了component-scan逻辑,这里确实会有InstantiationAwareBeanPostProcessor类型的后处理器,但是这三个后处理器内部的applyBeanPostProcessorsBeforeInstantiation方法都返回了一个空值,因此,如果采用默认的后处理器,其实resolveBeforeInstantiation方法没有干任何事情。
4.2 doCreateBean
真正实例化一个对象通常分为三步骤:实例化-》属性填充-》初始化。




4.2.1 createBeanInstance
我们先来看看第一个步骤,如何实例化一个Bean,它的一个核心思想是获取构造器通过反射完成实例化:


4.2.1.1 determineConstructorsFromBeanPostProcessors
determineConstructorsFromBeanPostProcessors方法主要通过回调后处理器的determineCandidateConstructors方法来获取候选构造器:

当前beanFactory中有确实有两个后处理器是SmartInstantiationAwareBeanPostProcessor类型的:ImportAwareBeanPostProcessor和AutowiredAnnotationBeanPostProcessor。
其中ImportAwareBeanPostProcessor里面的determineCandidateConstructors方法是空实现,获取候选构造器的主要逻辑在AutowiredAnnotationBeanPostProcessor的determineCandidateConstructors方法中。
需要注意的是:

让我们继续进入到AutowiredAnnotationBeanPostProcessor中的determineCandidateConstructors方法去看看,是如何获得候选构造器的,由于代码太长,分块讲解一下:



根据2.4中的逻辑,可以得到以下结论:
1.如果有两个及以上构造器的@Autowired注解的required属性为true,抛出异常。
2.当有一个构造器的@Autowired注解的required属性为true,不允许有其他@Autowired注解。
3.当有一个构造器的@Autowired注解的required属性为true,不会考虑无参构造。
4.当有多个@Autowired注解,并且required属性都为false,这些构造器和无参构造器都会加入到候选构造器数组中。
4.2.1.2 autowireConstructor
前面已经通过determineConstructorsFromBeanPostProcessors获得了候选构造器ctors,接下来就就要对候选构造器中的参数进行解析注入,并实例化对象。
autowireConstructor底层是通过创建ConstructorResolver对象,然后调用ConstructorResolver的autowireConstructor方法,还是采取分块解析的方式:






4.2.1.3 简单看看instantiate干了什么
获得当前工厂的策略器,默认是CglibSubclassingInstantiationStrategy,该策略器调用父类SimpleInstantiationStrategy的instantiate方法完成Bean的实例化:



4.2.2 applyMergedBeanDefinitionPostProcessors

可以看到当前beanFactory中的后处理器中,有三个都是MergedBeanDefinitionPostProcessor类型的,分别去回调里面的postProcessMergedBeanDefinition方法。

简单说说这三个MergedBeanDefinitionPostProcessor类型的后处理器里面的postProcessMergedBeanDefinition方法:
AutowiredAnnotationBeanPostProcessor后处理器处理@Autowired、@Value、@Inject注解的字段和成员方法,将这些信息保存下来。

让我们简单看看buildAutowiringMetadata方法:

ApplicationListenerDetector后处理器主要来缓存单例的ApplicationListener的beanName:

我们之前也提到过,ApplicationListenerDetector也重写了postProcessAfterInitialization方法,该方法会在bean初始化结束后执行:

CommonAnnotationBeanPostProcessor后处理器处理@WebServiceRef、@EJB、@Resource注解,其postProcessMergedBeanDefinition方法的逻辑和AutowiredAnnotationBeanPostProcessor一致,这里就不贴源代码了。
4.2.2 addSingletonFactory

可以看到缓存到第三级缓存中的是一个lambda表达式,当我们从singletonFactories中获取该bean时,返回的其实是getEarlyBeanReference的返回值,getEarlyBeanReference的实现如下:

SmartInstantiationAwareBeanPostProcessor类型的后处理器其实在createBeanInstance时也用过,当时是通过回调后处理器的determineConstructorsFromBeanPostProcessors方法来获得候选构造器,这里是调用getEarlyBeanReference。当前beanFactory中有六个后处理器其中有俩属于SmartInstantiationAwareBeanPostProcessor:

有意思的是,它的实现类也都是默认返回传递的参数bean实例,也就是说Spring在这个扩展点方法中没有任何额外操作。
4.2.3 populateBean


4.2.4 initializeBean
在完成实例化和属性填充后开始初始化操作,包括回调各种方法,并执行自己的init方法(如果有的话):

