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,这些构造器和无参构造器都会加入到候选构造器数组中。![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/e0853890a2884ada9e0bcb8eae0f4bbd.png#pic_center)
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方法(如果有的话):