什么是Bean的生命周期
- Bean 的生命周期就是:对象从创建开始到最终销毁的整个过程,Bean 对象从创建到销毁中经历了哪些过程
- 什么时候创建Bean对象?
- 创建Bean对象的前后会调用什么方法?
- Bean对象什么时候销毁?
- Bean对象的销毁前后调用什么方法?
- Spring其实就是一个管理Bean对象的工厂,它负责对象的创建,对象的销毁等。
为什么要知道Bean的生命周期
- 生命周期的本质是:在哪个时间节点上调用了哪个类的哪个方法。
- 我们需要充分的了解在这个生命线上,都有哪些特殊的时间节点,在这些特殊节点会调用哪个类的哪个方法。
- 我们可能需要在某个特殊的时间点上执行一段特定的代码,只有我们知道了特殊的时间节点都在哪,在该特殊节点会调用什么方法,我们才可以确定代码写到哪,这段代码就可以放到这个节点上,当生命线走到这里的时候,自然会被调用。
Bean的生命周期之5步
-
Bean生命周期的管理,可以参考Spring的源码:AbstractAutowireCapableBeanFactory类的doCreateBean()方法。
-
Bean生命周期可以粗略的划分为五大步:
-
第一步:实例化Bean,调用无参构造方法创建对象
-
第二步:Bean属性赋值,调用对象的set方法,进行set注入
-
第三步:初始化Bean,调用Bean的init方法(该方法需要自己写,然后进行配置)
-
第四步:使用Bean
-
第五步:销毁Bean,调用Bean的Destroy方法(该方法需要自己写,然后进行配置)
-
进行Bean的销毁,必须关闭Spring容器,只有关闭了Spring容器,Bean才会进行销毁
Bean生命周期之7步
-
Bean生命周期七步,比Bean生命周期五步,在初始化Bean的前和后,添加了两步。
-
在以上的5步中,第3步是初始化Bean,在初始化前和初始化后执行的方法为“Bean后处理器”的before和after方法,通过“Bean后处理器”我们可以在初始化Bean的前后添加需要执行的代码。
-
要添加“Bean后处理器”需要类实现BeanPostProcessor类,并且重写before和after方法
-
Bean生命周期之7步:
-
第一步:实例化Bean
-
第二步:Bean属性赋值
-
第三步:执行“Bean后处理器”的before方法。
-
第四步:初始化Bean
-
第五步:执行“Bean后处理器”的after方法。
-
第六步:使用Bean
-
第七步:销毁Bean
Bean生命周期之十步
-
Bean生命周期十步比七步多的三步:
-
点位1:在“Bean后处理器”before方法之前,在Bean属性赋值之后
-
点位2:在“Bean后处理器”before方法之后,在Bean的初始化之前
-
点位3:使用Bean之后,或者说销毁Bean之前
-
添加的这三个点位的特点:都是在检查你这个Bean是否实现了某些特定的接口,如果实现了这些接口,则Spring容器会调用这个接口中的方法。
实现 Aware 相关接口:
-
Aware相关的接口包括:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
-
当Bean实现了BeanNameAware,Spring会将Bean的名字传递给Bean。
-
当Bean实现了BeanClassLoaderAware,Spring会将加载该Bean的类加载器传递给Bean。
-
当Bean实现了BeanFactoryAware,Spring会将Bean工厂对象传递给Bean。
-
在“Bean后处理器”before方法之前,会检查Bean是否实现了Aware相关的接口,如果实现了接口则调用这些接口中的方法。然后调用这些方法的目的是为了给你传递一些数据,让你更加方便使用。
完整生命周期
1.创建 Bean 的实例:Bean 容器首先会找到配置文件中的 Bean 定义,然后使用 Java 反射 API 来创建 Bean 的实例。
2.Bean 属性赋值/填充:为 Bean 设置相关属性和依赖,例如@Autowired
等注解注入的对象、@Value
注入的值、setter
方法或构造函数注入依赖和值、@Resource
注入的各种资源。
3.Bean 初始化:
1.检查Aware相关接口
- 如果 Bean 实现了
BeanNameAware
接口,调用setBeanName()
方法,传入 Bean 的名字。 - 如果 Bean 实现了
BeanClassLoaderAware
接口,调用setBeanClassLoader()
方法,传入ClassLoader
对象的实例。 - 如果 Bean 实现了
BeanFactoryAware
接口,调用setBeanFactory()
方法,传入BeanFactory
对象的实例。 - 与上面的类似,如果实现了其他
*.Aware
接口,就调用相应的方法。
2.调用Bean后处理器(BeanPostProcessor)的before方法 - 如果有和加载这个 Bean 的 Spring 容器相关的
BeanPostProcessor
对象,执行postProcessBeforeInitialization()
方法
3.检查InitializingBean接口 - 如果 Bean 实现了
InitializingBean
接口,执行afterPropertiesSet()
方法。 - 如果 Bean 在配置文件中的定义包含
init-method
属性,执行指定的方法。
4.实现Bean后处理器(BeanPostProcessor)的after方法 - 如果有和加载这个 Bean 的 Spring 容器相关的
BeanPostProcessor
对象,执行postProcessAfterInitialization()
方法。
5.销毁 Bean:销毁并不是说要立马把 Bean 给销毁掉,而是把 Bean 的销毁方法先记录下来,将来需要销毁 Bean 或者销毁容器的时候,就调用这些方法去释放 Bean 所持有的资源。
- 如果 Bean 实现了
DisposableBean
接口,执行destroy()
方法。 - 如果 Bean 在配置文件中的定义包含
destroy-method
属性,执行指定的 Bean 销毁方法。或者,也可以直接通过@PreDestroy
注解标记 Bean 销毁之前执行的方法。
如何记忆呢?
- 整体上可以简单分为四步:实例化 —> 属性赋值 —> 初始化 —> 销毁。
- 初始化这一步涉及到的步骤比较多,包含
Aware
接口的依赖注入、BeanPostProcessor
在初始化前后的处理以及InitializingBean
和init-method
的初始化操作。 - 销毁这一步会注册相关销毁回调接口,最后通过
DisposableBean
和destory-method
进行销毁。