【spring源码系列】之【Bean的生命周期】
目录
为源码付出的每一分努力都不会白费。
1. Bean的实例化概述
前一篇分析了BeanDefinition的封装过程,最终将beanName与BeanDefinition以一对一映射关系放到beanDefinitionMap容器中,这一篇重点分析如何利用bean的定义信息BeanDefinition实例化bean。
2. 流程概览
其实bean的实例化过程比较复杂,中间细节很多,为了抓住重点,先将核心流程梳理出来,主要包含以下几个流程:
step1
: 通过反射创建实例;step2
:给实例属性赋初始值;step3
:如果Bean类实现BeanNameAware接口,则将通过传递Bean的名称来调用setBeanName()方法;如果Bean类实现BeanClassLoaderAware接口,则将通过传递加载此Bean的ClassLoader对象的实例来调用setBeanClassLoader()方法;如果Bean类实现BeanFactoryAware接口,则将通过传递BeanFactory对象的实例来调用setBeanFactory()方法;step4
: 如果有类实现BeanPostProcessors接口,则将在初始化之前调用postProcessBeforeInitialization()方法;step5
:如果Bean类实现了InitializingBean接口,将调用afterPropertiesSet()方法,如果配置文件中的Bean定义包含init-method属性,则该属性的值将解析为Bean类中的方法名称,并将调用该方法;step6
: 如果有类实现BeanPostProcessors接口,则将在初始化之后调用postProcessAfterInitialization()方法;step7
:如果Bean类实现DisposableBean接口,则当Application不再需要Bean引用时,将调用destroy()方法;如果配置文件中的Bean定义包含destroy-method属性,那么将调用Bean类中的相应方法定义。
3. 源码分析
进入AbstractApplicationContext中的fresh()方法,找到finishBeanFactoryInitialization(beanFactory)方法,该类是bean的实例化的入口,具体的实例化由preInstantiateSingletons()方法触发,见如下代码:
上述代码主要看getBean
方法,随后进入doGetBean
方法:
由上述代码可知,先从缓存中获取bean,如果没有,则创建bean,最重要的方法就是getSingleton,该方法第二个参数是个函数式接口,进入getSingleton方法,当调用singletonObject = singletonFactory.getObject()
时,会触发函数式接口中的createBean方法,随后一路进入doCreateBean,这个方法里面完成了所有实例化所需的步骤:
从上述源码中看出bean的实例化主要分为以下三步:step1
:bean的创建;step2
:给bean的属性赋值;step3
:bean的初始化;
接着得到exposedObject这个已经完全实例化后的bean返回,其中当有必要时,注册bean的销毁,后面再详细看,先抓住主要流程。其中step3也是比较重要的方法,进入该方法:
从上面源码可知,梳理出主要的四个步骤:step1
:激活aware接口,完成aware接口的相关操作;step2
:初始化前处理的beanPostProcessor;step3
:完成init-method方法;step4
:初始化后处理的beanPostProcessor;
BeanPostProcessor作用是对初始化后的bean进行增强处理,在该阶段 BeanPostProcessor 会处理当前容器内所有符合条件的实例化后的 bean 对象。它主要是对 Spring 容器提供的 bean 实例对象进行有效的扩展,允许Spring在初始化 bean 阶段对其进行定制化修改,如处理标记接口或者为其提供代理实现。
4. 演示
定义一个MyBeanPostProcessor实现BeanPostProcessor接口
定义一个LifeCycleBean类,实现如下接口:
指定配置文件spring.xml,配置init-method
与destroy-method
方法
测试类如下:
执行结果:
4. 总结
本篇从一个初学者的角度概览了bean的整个生命周期,并描述了其中的主要流程,阅读源码的初始阶段,优先抓住主要流程,别陷入细节,并通过跑案例、写注解、画流程图等方式加深理解,后续将继续分析bean实例化中的核心流程、设计思想等。