文章目录

  • Bean有哪些
  • Bean的生命周期
  • 一、生产
  • 1.加载Bean定义
  • 2.创建Bean对象
  • 2.1构造对象
  • 具体过程是:
  • 拿取构造方法的规则
  • 2.2填充属性
  • 2.3初始化实例
  • 有哪些处理器
  • 2.4注册销毁
  • 3.添加到单例池
  • 二、使用
  • 三、销毁
  • 4.销毁
  • 4.1销毁前
  • 4.2销毁
  • 4.3执行客户自定义销毁


Bean有哪些

分为两大类系统Bean和客户自定义Bean
系统Bean包括:dataSource、templete、adapter、executor…
客户自定义Bean就是程序员编写的各种Bean(生命周期存在的意义就是帮助程序员妥善管理和使用这些Bean)

Bean的生命周期

Bean在IOC中会经过生产、使用、销毁三个大的阶段(其中生产阶段最为复杂)
在程序员启动时,Spring就准备开始生产Bean(启动过程很复杂,包括准备容器、环境等)

一、生产

1.加载Bean定义

在启动之初为了了解对于Bean的要求,通过“加载Bean定义” loadBeanDefinitions方法扫描所有xml配置、注解将Bean记录在Spring容器中的一个“Bean定义”集合中,即beanDefinitionMap

2.创建Bean对象

有了这些“Bean定义”集合之后,就可以遍历这个集合,然后通过 createBean 遍历 beanDefinitionMap 创建bean。
创建Bean大体分为“构造对象、填充属性、初始化实例、注册销毁”这四个步骤

2.1构造对象

容器通过 createBeanInstance 进行对象构造

具体过程是:

(1)先用反射机制从“Bean定义”中的BeanClass拿到这个类的构造方法

拿取构造方法的规则

如果这个Bean只有一个构造方法,那就拿它(无论这个构造方法有没有入参)
如果这个Bean有多个构造方法时,先拿带有@Autowired注解的构造方法
若多个构造方法都加了@Autowired注解,没有办法判断程序员到底是想让容器用哪个方法进行构造,所以只能报错
若构造方法都没有@Autowired注解,就会优先拿无入参的构造方法
若多个构造方法都是有入参的,没办法判断断程序员到底是想让容器用哪个方法进行构造,所以只能报错

总结:在开发过程中不建议在任何Bean中添加多个构造方法,因为这样可读性低,理解和维护会很困难

(2)在选择好那个构造方法后,就要准备这个构造方法需要的参数
容器会在单例池中根据参数的Class类进行过查找,如果这个类在容器中有多个实例,则会根据参数名在进行匹配,如果没有找到,容器就会认为构造信息导致不完整而直接报错
总结:根据类查找–>参数名查找

(3)在参数准备好之后,通过反射就可以进行Bean的构造,即实例化
如果选择的时无参构造方法,则无须参数直接构造

2.2填充属性

在Bean对象构造成功后,就需要进行填充属性。
通过populateBean方法为Bean内部所需的属性进行赋值填充

对象:通常就是 @Autowired 注解的变量

容器会通过“三级缓存”机制进行填充,即依赖注入

2.3初始化实例

在属性填充后,通过initializeBean对填充后的实例进行初始化
初始化的步骤:
(1)初始化容器相关信息
通过 invokeAwareMethods 方法为实现了各种Aware接口【信息感知接口】的Bean 设置诸如beanName、beanFactory等容器信息
注意:容器中的Aware的接口代表“信息感知”接口,一旦实现了这些接口,就可以在bean实例中感知并获取到对应的信息

(2)执行Bean的初始化方法
通过 invokeInitMethods 方法执行Bean的初始化方法
该初始化方法是程序员通过实现InitializingBean接口而实现的afterPropertiesSet方法(该方法名很直接,表示“Bean、填充属性后”执行)
在afterPropertiesSet方法执行后,还会继续执行程序员在Bean上自定义的initMethod方法

而在执行初始化initMethod方法前后,还需要对“Bean后置处理器”BeanPostProcessors进行处理(通过以下两个方法在初始化之前和之后处理各种Bean的后置处理器)

applyBeanPostProcessorsBeforeInitialization
 invokeInitMethods
applyBeanPostProcessorsAfterInitialization
有哪些处理器

这些处理器包括容器自身提供的“负责AOP处理”的AnnotationAwareAspectJAutoProxyCreator、负责构造后@PostConstruct 和 销毁前@PreDestroy 的 InitDestoryAnnotationBeanPostProcessor 等“系统级处理器”、程序员通过实现BeanPostProcessor接口的“自定义”处理器

这些处理器有很多,通过实现PriorityOrdered接口来指定顺序进行逐一处理

2.4注册销毁

以上步骤完成时,Bean实例已经可以使用了
为了让Bean实例优雅地销毁,通过注册reigsterDisposableBean方法将实现了DisposableBean接口的Bean进行注册,这样在销毁时就可以执行destory方法了

3.添加到单例池

通过以上四步就将Bean创建好了,最后只需要将这些完整的Bean对象通过addSingleton方法放入单例池singletonObjects中就可以被获取和使用,这样“产生Bean”就全部完成了。

二、使用

接下来,程序员就可以任意地在容器中使用这些Bean了。

三、销毁

4.销毁

最后当容器执行close关闭时,和“产生Bean”类似

4.1销毁前

(1)在销毁之前要先执行“销毁前处理器”postProcessBeforeDestruction,这里就会执行Bean中的@PreDestroy注解的方法,

4.2销毁

(2)然后通过destroyBeans方法逐一“销毁”容器中所有的Bean,销毁时会执行刚才提到的destroy方法,

4.3执行客户自定义销毁

(3)在destroy执行之后,也会通过“客户销毁方法”invokeCustomDestroyMethod来执行程序员在Bean上自定义的destroyMethod方法