Spring源码中的Bean生命周期

214 阅读4分钟

学习Spring框架时,了解Bean的生命周期是非常重要的。Bean的生命周期是指,在Spring容器中,Bean从创建到销毁的整个过程。本文将从Spring源码的角度来分析Bean的生命周期。

Spring Bean的生命周期

Bean的生命周期分为以下几个阶段:

  1. 实例化:Spring容器通过构造器或工厂方法创建出Bean的实例。这个过程是实例化阶段。
  2. 属性注入:Spring容器利用Setter方法或直接访问成员变量,将Bean的属性设置为相应的值。这个过程是属性注入阶段。
  3. 初始化:Bean对象的属性都被设置之后,Spring容器会对Bean进行初始化。如果Bean实现了InitializingBean接口,Spring容器会调用它的afterPropertiesSet方法;如果这个Bean配置了init-method,则调用该方法。
  4. 使用:Bean被初始化之后,可以被容器使用。在使用期间,Bean可能会被多次访问。
  5. 销毁:当容器关闭时,Spring容器要负责将Bean销毁掉。如果Bean实现了DisposableBean接口,Spring容器会调用它的destroy方法;如果这个Bean配置了destroy-method,则调用该方法。

Spring源码分析

实例化

Bean的实例化是由BeanFactory负责的。BeanFactory在创建Bean的实例时,实际上是通过调用Bean的构造器或通过工厂方法来创建出Bean的实例。这个过程是比较简单的。

public abstract class AbstractBeanFactory extends DefaultSingletonBeanRegistry implements ConfigurableBeanFactory, BeanDefinitionRegistry { 
    //创建bean的实例 
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { 
       //实例化处理器 
       InstantiationStrategy InstantiationStrategy strategy = this.getInstantiationStrategy();        //执行实例化过程 
       Object bean = strategy.instantiate(mbd, beanName, this); 
       return bean; 
     } 
 } 

其中,InstantiationStrategy是一个接口类型,用于定义Bean的实例化策略。Spring提供了两种实例化策略:SimpleInstantiationStrategyCglibSubclassingInstantiationStrategy

属性注入

Bean的属性注入会在Bean的实例化之后进行。Spring容器会根据Bean的配置信息,调用Setter方法或直接访问成员变量,将Bean的属性设置为相应的值。

public Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { 
    //属性填充器 
    MergedBeanDefinitionPostProcessor pvs = null; 
    int beanPhase = 0; 
    if (logger.isTraceEnabled()) { 
       logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); 
    } 
    //判断是否实现了AutowiredAnnotationBeanPostProcessor,实现了则获取到它
    if (mbd == null || !mbd.isSynthetic()) { 
        pvs = this.postProcessMergedBeanDefinition(mbd, bean.getClass(), beanName); 
    } 
    if (pvs != null) { 
        if (pvs.postProcessAfterInstantiation(bean, beanName)) { 
           return this.wrapBeanIfNecessary(bean, beanName, pvs); 
        } 
     } 
     //应用属性填充器 
     applyBeanPostProcessorsBeforeApplyingPropertyValues(beanName, bean, mbd); 
     BeanWrapper bw = null; 
     //进行属性注入,暴露一个属性值的解析器接口 
     if (mbd != null) { 
        bw = this.applyBeanPropertyValues(beanName, bean, mbd, pvs); 
     } 
     beanPhase = 2; 
     //执行验证,类型转换等工作 
     if (bw != null) {        
         this.applyBeanPostProcessorsAfterApplyingPropertyValues(bean, beanName); 
     } 
     return bean; 
} 

初始化

Bean的初始化会在Bean的属性注入之后进行,Spring容器会根据Bean的配置信息,调用相应的初始化方法。

public Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { 
   //... 
   //调用InitializingBean.afterPropertiesSet进行初始化 
   if (mbd == null || !mbd.isSynthetic()) { 
      //回调调用aware接口的方法 
      invokeAwareMethods(beanName, bean); 
   } 
    //执行BeanPostProcessor的postProcessBeforeInitialization方法 
    Object wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName); 
    try { 
       //执行初始化(如果实现了InitializingBean接口)和init-method属性指定的初始化方法 
       invokeInitMethods(beanName, wrappedBean, mbd); 
    } catch (Throwable ex) { 
       //... 
    } 
    //执行BeanPostProcessor的postProcessAfterInitialization方法 
    wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);          //... 
    return wrappedBean; 
 } 

其中,InitializingBean是一个接口类型,包含了一个方法afterPropertiesSet,该方法会在Bean属性注入之后执行。如果Bean实现了InitializingBean接口,Spring容器会调用它的afterPropertiesSet方法。

使用

当Bean经过初始化之后,可以被Spring容器使用。在使用期间,Bean可能会被多次访问。使用期间,Spring容器不会对Bean进行任何修改。

销毁

当Spring容器关闭时,会自动调用销毁方法。如果Bean实现了DisposableBean接口,Spring容器会调用它的destroy方法;如果这个Bean配置了destroy-method,则调用该方法。 、

public void destroyBean(final String beanName, final Object beanInstance) { 
    //执行销毁操作,先执行destroy方法,然后将其从容器中移除 
    try { 
       if (beanInstance instanceof DisposableBean) { 
          ((DisposableBean) beanInstance).destroy(); 
       } 
       if (this.hasDestructionAwareBeanPostProcessors()) { 
          for (DestructionAwareBeanPostProcessor processor :getBeanPostProcessorCache().destructionAware) { 
          processor.postProcessBeforeDestruction(beanInstance, beanName); 
          } 
       } 
   } catch (Throwable ex) { 
   //... 
   }
} 

总结

Spring Bean的生命周期很清晰的被划分为实例化、属性注入、初始化、使用和销毁这几个阶段。从Spring源码角度来说,很多操作都是通过实现相应的接口,然后通过一些钩子方法来触发的。了解Bean的生命周期是开发Spring应用的必备知识之一。