上一节我们讲到《【Spring6源码・IOC】BeanDefinition的加载》,这一节我们来讲解一下Bean的实例化。
根据xml或注解加载完Bean的信息后,最终会通过反射来创建bean的对象。
invokeBeanFactoryPostProcessors()主要是加载BeanDefinition。
finishBeanFactoryInitialization这个方法就是实例化的入口。
步入这个方法,最后会调用DefaultListableBeanFactory#preInstantiateSingletons来加载所有懒加载的Bean。
步入这个方法中,首先将我们之前加载的Bean信息BeanDefinition放进一个新的List集合中,而后循环遍历每一个Bean,做相关操作。
进入getBean()方法之后,这离会有一个核心方法doGetBean()
我们来仔细看一下这个AbstractBeanFactory#doGetBean方法
首先会根据beanName通过getSingleton()方法从缓存中获取对象的bean,可是此时该Bean还未进行实例化,所以返回的是null。
进入getSingleton()方法中,首先会从一级缓存中查找对象,此时一定是没有的,接下来通过isSingletonCurrentlyInCreation(beanName)来判断该Bean是否正在创建中,当然也是没有。所以上面返回的对象sharedInstance为null。
进而进入else分支,首先判断这个bean有没有依赖其他的bean,也就是说是否有@DependsOn注解,如果有的话,会在该bean创建之前实例化@DependsOn注解中的bean,我们这个bean显然没有,而后,会判断该bean是否是单例的。
因为我们没有做任何配置,故,其默认就是单例的。
如下
同样是调用了getSingleton方法,与上面不同的是,这里传入了一个lambda函数,这一看就是创建bean的嘛,我们来看一看。
步入这个getSingleton方法,首先从一级缓存中获取该bean,因为仍未进行实例化,故为null。
进而会调用ObjectFactory#getObject,从而调用我们的lambda函数,去创建bean。
看这个lambda函数
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
});
这个createBean方法中有一个关键的方法:doCreateBean
让我们看一看,因为我们还未进行初始化,所以instanceWrapper为null,则createBeanInstance(beanName, mbd, args)
为创建bean的方法
步入该方法最后进入instantiateBean方法进行bean的实例化。
这个方法中,我们通过BeanDefinition、beanName、和当前容器去创建bean,并且将其返回。
我们来看看是如何创建的。
首先获取构造器,然后将构造器传入BeanUtils.instantiateClass(constructorToUse)
进入该方法,发现都是我们的熟悉的流程,哈哈哈哈,首先通过构造器获取构造参数,显然我们这里的构造方法为无参构造方法,所以parameterCount为0,调用197行代码。如果有参数的话,就会调用210行代码,就此,我们的bean实例化成功。
最后把已经实例化,但未经初始化的bean放进第三级缓存中,宣告着bean的实例化彻底结束。