这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战
【单实例 bean 】 的全生命周期为主线讨论,具体包含以下部分:
BeanDefinition
部分
+ `BeanDefinition` 的解析
+ `BeanDefinition` 的注册
- bean 实例部分
+ bean 的实例化
+ bean 的属性赋值 + 依赖注入
+ bean 的初始化流程
+ bean 的启动与停止
+ bean 的销毁
我们就可以对 Spring Bean 的声明周期过程如下****(方法级别**):准确来说是实例化部分的生命周期
1.Spring 容器根据实例化策略对 Bean 进行实例化。
在实例化 bean 过程中,Spring 采用“策略模式”来决定采用哪种方式来实例化 bean,一般有反射和 CGLIB 动态字节码两种方式。默认情况下,Spring 采用 CglibSubclassingInstantiationStrategy。
2.实例化完成后,如果该 bean 设置了一些属性的话,则利用 set 方法设置一些属性。
3.如果该 Bean 实现了 BeanNameAware 接口,则调用 #setBeanName(String beanName)
方法。
Aware 接口为 Spring 容器的核心接口,是一个具有标识作用的超级接口,实现了该接口的 bean 是具有被 Spring 容器通知的能力,通知的方式是采用回调的方式
4.如果该 bean 实现了 BeanClassLoaderAware 接口,则调用 setBeanClassLoader(ClassLoader classLoader)
方法。
5.如果该 bean 实现了 BeanFactoryAware接口,则调用 setBeanFactory(BeanFactory beanFactory)
方法。
6.如果该容器注册了 BeanPostProcessor,则会调用#postProcessBeforeInitialization(Object bean, String beanName)
方法,完成 bean 前置处理
初始化第二个阶段则是BeanPostProcessor 增强处理,在该阶段 BeanPostProcessor 会处理当前容器内所有符合条件的实例化后的 bean 对象。它主要是对 Spring 容器提供的 bean 实例对象进行有效的扩展,允许 Spring 在初始化 bean 阶段对其进行定制化修改,如处理标记接口或者为其提供代理实现。
7.如果该 bean 实现了 InitializingBean 接口,则调用#afterPropertiesSet()
方法。
8.如果该 bean 配置了 init-method
方法,则调用其指定的方法。
9.初始化完成后,如果该容器注册了 BeanPostProcessor 则会调用 #postProcessAfterInitialization(Object bean, String beanName)
方法,完成 bean 的后置处理。
10.对象完成初始化,开始方法调用。
11.在容器进行关闭之前,如果该 bean 实现了 DisposableBean 接口,则调用 #destroy()
方法。
12.在容器进行关闭之前,如果该 bean 配置了 destroy-method
,则调用其指定的方法。
13.到这里一个 bean 也就完成了它的一生。
小结:
首先,bean 的生命周期分为 BeanDefinition
阶段和 bean 实例阶段。
1)BeanDefinition
阶段分为加载 xml 配置文件、解析注解配置类、编程式构造 BeanDefinition
、BeanDefinition
的后置处理,一共四个部分
2)bean 实例阶段的生命周期包含四大步骤:
a)bean 的实例化 b)属性赋值 + 依赖注入 c)bean 的初始化生命周期回调 d)bean 实例的销毁
注:理解 bean 的生命周期,首先要从 BeanDefinition
开始切入,由 BeanDefinition
再到 bean 实例,这个回答的逻辑和脉络才是一个好的回答
本文转载自: 掘金