Bean的生命周期
在 Spring 框架中,Bean 的生命周期是由 Spring 容器全权管理的。从实例化 Bean 到 Bean 的销毁,这个生命周期涉及多个步骤和回调方法。我们可以通过 Spring 源码来了解 Bean 的生命周期的每一个步骤。下面我们从源码角度剖析 Bean 的生命周期。
Bean 生命周期的关键步骤:
- BeanDefinition 加载:Spring 加载并解析 Bean 的定义,将其存储在容器中。
- Bean 实例化:通过反射创建 Bean 实例。
- 依赖注入:将属性值和依赖注入到 Bean 中。
- Aware 回调:如果实现了相关 Aware 接口,调用它们的回调方法。
- BeanPostProcessor 前置处理:在初始化方法调用之前执行。
- 初始化:调用
InitializingBean.afterPropertiesSet()
或者自定义init-method
。 - BeanPostProcessor 后置处理:在初始化方法调用之后执行。
- Bean 销毁:在容器关闭时,调用
DisposableBean.destroy()
或者自定义destroy-method
。
1. Bean 的定义与加载
Spring Bean 的生命周期开始于它的定义阶段。在这一步,Spring 会将配置信息(例如 XML 文件或 Java 配置类)加载到容器中,解析出 Bean 的定义(BeanDefinition
),将其存储在 Spring 容器内。
源码路径:DefaultListableBeanFactory.java
在 DefaultListableBeanFactory
的 registerBeanDefinition
方法中,我们可以看到 Spring 通过 BeanDefinition
对象注册 Bean 定义:
2. Bean 的实例化
Spring 根据 BeanDefinition
来实例化 Bean 对象。实例化过程通常通过反射机制调用 Bean 的构造器。
源码路径:AbstractAutowireCapableBeanFactory.java
在 AbstractAutowireCapableBeanFactory
类的 createBeanInstance
方法中,可以看到 Spring 是如何实例化 Bean 的:
java
复制代码
protected Object createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { // 创建 Bean 实例,这里通常使用构造器反射来创建对象 return this.instantiateBean(beanName, mbd); }
3. 属性填充
Bean 实例化完成后,Spring 会进行依赖注入(DI),将配置中的属性值注入到该 Bean 实例中。这个步骤包括自动装配和通过配置文件或注解进行的属性注入。
源码路径:AbstractAutowireCapableBeanFactory.java
populateBean
方法负责属性填充:
java
复制代码
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { // 这里完成依赖注入(属性的填充) applyPropertyValues(beanName, mbd, bw, pvs); }
4. Bean 的初始化
当 Bean 实例化并填充完属性之后,Spring 会对 Bean 进行初始化。初始化过程涉及多种机制,例如:
- 调用
BeanNameAware
、BeanFactoryAware
、ApplicationContextAware
等接口的回调方法。 - 调用
InitializingBean
接口的afterPropertiesSet()
方法。 - 调用配置在 XML 或 Java 配置类中的自定义
init-method
。
4.1. Aware 接口回调
如果 Bean 实现了 BeanNameAware
、BeanFactoryAware
等接口,Spring 会在初始化之前调用这些接口的相应方法。例如,setBeanName
可以获取到 Bean 的名称。
源码路径:AbstractAutowireCapableBeanFactory.java
java
复制代码
private void invokeAwareMethods(String beanName, Object bean) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(this); } }
4.2. InitializingBean
接口回调
如果 Bean 实现了 InitializingBean
接口,Spring 会调用 afterPropertiesSet()
方法进行初始化。
java
复制代码
if (bean instanceof InitializingBean) { ((InitializingBean) bean).afterPropertiesSet(); }
4.3. 自定义 init-method
回调
如果在 Bean 定义中指定了 init-method
,Spring 会通过反射调用该方法。
java
复制代码
if (mbd.getInitMethodName() != null) { invokeCustomInitMethod(beanName, bean, mbd.getInitMethodName()); }
5. BeanPostProcessor 的处理
在初始化的前后,Spring 还允许通过 BeanPostProcessor
对 Bean 进行自定义的处理。Spring 提供了两种回调方法:
postProcessBeforeInitialization(Object bean, String beanName)
:在初始化方法调用之前执行。postProcessAfterInitialization(Object bean, String beanName)
:在初始化方法调用之后执行。
源码路径:AbstractAutowireCapableBeanFactory.java
java
复制代码
// 初始化前的 BeanPostProcessor 调用 bean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); // 初始化后的 BeanPostProcessor 调用 bean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
6. Bean 的销毁
当容器关闭或 Bean 被销毁时,Spring 也会调用一些回调方法来进行资源的释放。
- 如果 Bean 实现了
DisposableBean
接口,Spring 会调用destroy()
方法。 - 如果在 Bean 定义中配置了
destroy-method
,Spring 也会通过反射调用该方法。
源码路径:DisposableBeanAdapter.java
java
复制代码
public void destroy() { // 如果实现了 DisposableBean,调用 destroy 方法 if (this.invokeDisposableBean) { invokeCustomDestroyMethod(this.bean, this.destroyMethodName); } }
原文地址:https://blog.csdn.net/sdg_advance/article/details/143031217
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!