飞道的博客

【Spring6源码・IOC】Bean的实例化

289人阅读  评论(0)

上一节我们讲到《【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的实例化彻底结束。


转载:https://blog.csdn.net/CSDN_SAVIOR/article/details/128608748
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场