从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期

从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期

我们所说的Bean的生命周期指的是从Bean的创建、初始化、使用Bean、销毁的整个过程。而IOC容器就是负责管理Bean的整个生命周期。实际上Bean的生命周期在容器启动的时候就已经开始了,严格来说,你可以认为容器启动时,从注解配置读取器读取标有注解的类,转换为BeanDefinition对象时,Bean的生命周期就已经开始了。打个比方,小宝宝的生命的起点,并不是说从出生落地开始算的,而是从妈妈肚子里面,基本上可以算是生命已经开始了。

我们在之前的IOC容器创建过程的文章中详细说明了容器的初始化和容器刷新的流程。我们说在执行refresh()方法刷新容器时,第11个阶段是创建剩余的所有单实例Bean

从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第1张图片
​首先遍历所集合中所有的Bean,根据Bean的name调用getBean()方法获取这个Bean
从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第2张图片

getBean()方法进一步调用doGetBean()方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oMxBhNiV-1632768559839)(C:\Users\Jian\AppData\Roaming\Typora\typora-user-images\image-20210927010651741.png)]
拿到bean的名字之后,先调用getSingleton()方法获取缓存中的单实例bean,如果能获取到,就说明这个bean之前已经被创建过了,因为所有创建过的单实例bean都会被缓存起来。
从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第3张图片

注意!如果缓存中获取不到,才算是真正开始创建Bean对象的流程!!!

首先标记当前bean已被创建,防止多线程创建同一个bean
从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第4张图片
然后获取bean定义信息,以及当前bean依赖的其它bean,如果有依赖就会调用getBean()方法把依赖的bean先创建出来
从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第5张图片
如果当前bean是单实例bean,就会启动单实例bean创建流程,会调用getSingleton()方法通过工厂的getObject()方法调用createBean()来创建bean。也就是说真正执行创建Bean的方法是这个createBean()方法

从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第6张图片

那么接下来就来详细说一说createBean()方法是如何创建Bean的

createBean()会先获取bean的定义信息
从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第7张图片
然后解析bean的类型

从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第8张图片

在Bean实例化之前,createBean()会调用resolveBeforeInstantiation()方法,会给Bean的后置处理器一个机会,**在实例化之前,让BeanPostProcessor先拦截返回代理对象,在实例化之前执行一些自定义逻辑,同时也会在实例化之后执行一些自定义逻辑。**也就是说,可以利用Bean的后置处理器,在Bean实例化前后的时间点,去执行一些我们自定义的操作逻辑。

如果说在这个Bean实例化之前,这个BeanPostProcessor后置处理器返回的代理对象不为null,就会直接返回这个代理对象。此时相当于跳过了容器默认的实例化过程,用这个代理对象替代了本该实例化的Bean对象。

从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第9张图片
从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第10张图片

如果前面的resolveBeforeInstantiation()方法没有返回一个代理对象,就会调用doCreateBean()方法去创建Bean对象

从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第11张图片

实际上这个doCreateBean()方法会调用createBeanInstance()方法创建一个bean实例

从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第12张图片

createBeanInstance()方法利用工厂方法或者对象的构造器创建出bean实例
从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第13张图片

doCreateBean()方法完成bean的创建之后,会调用populateBean()为创建出来的bean进行属性赋值。上面我们所说的由于直接返回代理对象,没有执行属性赋值,可以防止恶意的属性注入操作。

从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第14张图片

在赋值之前,会先获取BeanPostProcessor后置处理器,在实例化之后,初始化之前,利用这个后置处理器执行一些拦截操作。然后才是进行属性赋值。

从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第15张图片

完成属性赋值之后,会调用initializeBean()方法来初始化bean

从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第16张图片

initializeBean()方法会调用invokeAwareMethods()方法,执行各种实现了Aware接口的方法,比如设置bean的name、类加载器、beanFactory等信息。
从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第17张图片

然后调用applyBeanPostProcessorsBeforeInitialization()方法,后置处理器也会在bean初始化之前进行拦截
从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第18张图片

初始化之前的后置处理器执行完之后,就会调用invokeInitMethods()方法,执行初始化方法
从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第19张图片

invokeInitMethods()方法执行bean的初始化操作,执行那些实现了InitializingBean初始化接口,或者那些自定义的初始化的方法(使用注解或者init-method属性)

从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第20张图片

初始化结束之后,还会调用applyBeanPostProcessorsAfterInitialization()方法,执行初始化之后的后置处理器操作

从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第21张图片

至此bean的初始化完成

初始化执行完成之后,会调用registerDisposableBeanIfNecessary()方法注册bean的销毁方法,容器关闭的时候或者移除这个Bean的时候会调用销毁方法。

从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第22张图片

至此doCreateBean()方法执行结束,返回一个bean实例。整个doCreateBean()包含了实例化Bean、属性赋值、初始化Bean、注册销毁方法。

所以Spring容器的启动伴随着Bean生命周期的开始,整个Bean的生命周期如下图所示:

从Spring容器刷新过程中的创建Bean阶段来说说Bean的生命周期_第23张图片

你可能感兴趣的:(Spring框架,面试汇总,Java,spring,java,IOC容器,Bean生命周期,容器刷新)