自学内容网 自学内容网

Bean的生命周期

在 Spring 框架中,Bean 的生命周期是由 Spring 容器全权管理的。从实例化 Bean 到 Bean 的销毁,这个生命周期涉及多个步骤和回调方法。我们可以通过 Spring 源码来了解 Bean 的生命周期的每一个步骤。下面我们从源码角度剖析 Bean 的生命周期。

Bean 生命周期的关键步骤:

  1. BeanDefinition 加载:Spring 加载并解析 Bean 的定义,将其存储在容器中。
  2. Bean 实例化:通过反射创建 Bean 实例。
  3. 依赖注入:将属性值和依赖注入到 Bean 中。
  4. Aware 回调:如果实现了相关 Aware 接口,调用它们的回调方法。
  5. BeanPostProcessor 前置处理:在初始化方法调用之前执行。
  6. 初始化:调用 InitializingBean.afterPropertiesSet() 或者自定义 init-method
  7. BeanPostProcessor 后置处理:在初始化方法调用之后执行。
  8. Bean 销毁:在容器关闭时,调用 DisposableBean.destroy() 或者自定义 destroy-method

1. Bean 的定义与加载

Spring Bean 的生命周期开始于它的定义阶段。在这一步,Spring 会将配置信息(例如 XML 文件或 Java 配置类)加载到容器中,解析出 Bean 的定义(BeanDefinition),将其存储在 Spring 容器内。

源码路径DefaultListableBeanFactory.java

DefaultListableBeanFactoryregisterBeanDefinition 方法中,我们可以看到 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 进行初始化。初始化过程涉及多种机制,例如:

  • 调用 BeanNameAwareBeanFactoryAwareApplicationContextAware 等接口的回调方法。
  • 调用 InitializingBean 接口的 afterPropertiesSet() 方法。
  • 调用配置在 XML 或 Java 配置类中的自定义 init-method
4.1. Aware 接口回调

如果 Bean 实现了 BeanNameAwareBeanFactoryAware 等接口,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)!