Bean生命周期(二) 源码释读

本文深入探讨了Spring框架中Bean的生命周期,详细讲解了Bean的创建、初始化和销毁过程,包括实例化、初始化方法调用、Aware接口实现、BeanPostProcessor作用及@PostConstruct和@PreDestroy注解的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Bean生命周期(一) 浅尝知味 中,我们介绍了Bean的生命周期,并通过实验对其进行了验证,这次我们将从源码角度对其做进一步说明。整个Bean的生命周期,主要的逻辑就是实例化、初始化、销毁,而这些逻辑都集中在两个类里面,一个是 AbstractAutowireCapableBeanFactory,负责Bean的实例化与初始化,另外一个是 DisposableBeanAdapter,负责Bean的整个销毁流程。

Bean的创建

Bean的创建主要包括实例化与初始化两个阶段,都包含在 AbstractAutowireCapableBeanFactorycreateBean() 的方法中。

实例化

实例化指创建Bean实例的过程,这里泛指创建Bean及其前后 InstantiationAwareBeanPostProcessor 相关方法的调用,即 Bean生命周期(一) 浅尝知味 中的第一条支线。

首先,看下 createBean() 方法,由于篇幅的原因,只贴出部分核心的代码,其它部分都将使用省略号进行代替。

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {
   .......
   try {
      // 此处会调用 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation()
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {
         return bean;
      }
   }
   catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
   }

   try {
      // 剩下所有的步骤都在这个方法里面
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isTraceEnabled()) {
         logger.trace("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
   }
   catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
      throw ex;
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
   }
}

整个方法里面主要包含了两部分逻辑:

  1. 在创建Bean之前,通过resolveBeforeInstantiation() 方法对 InstantiationAwareBeanPostProcessorpostProcessBeforeInstantiation() 方法进行了调用;

  2. 调用 doCreateBean() 方法,该方法包含了除第一部分以外所有创建Bean的逻辑。

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {

   // 实例化Bean对象
   BeanWrapper instanceWrapper = null;
   if (mbd.isSingleton()) {
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
   }
   if (instanceWrapper == null) {
      // 调用Bean的构造方法
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }
   final Object bean = instanceWrapper.getWrappedInstance();
   Class<?> beanType = instanceWrapper.getWrappedClass();
   if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
   }

   ......

   // 初始化Bean实例
   Object exposedObject = bean;
   try {
      // 调用 InstantiationAwareBeanPostProcessor 的 postProcessAfterInstantiation() 方法 
      populateBean(beanName, mbd, instanceWrapper);
      // 完成Bean实例的初始化流程
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
   catch (Throwable ex) {
      if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
         throw (BeanCreationException) ex;
      }
      else {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
      }
   }
   
   ......
   
   return exposedObject;
}

doCreateBean() 方法里面,又分为两部分:

  1. 实例化Bean对象,通过反射调用Bean对象的构造方法,对其进行实例化,创建一个Bean实例。

  2. 初始化Bean实例

    1. 通过 populateBean() 方法完成对 InstantiationAwareBeanPostProcessorpostProcessAfterInstantiation() 方法调用。
    2. 调用 initializeBean() 完成剩余所有初始化动作。

至此,创建Bean流程的第一条线已经完成,用一个简单的时序图做一个阶段性的小结。

Bean创建的第一条线,完成Bean的实例化

初始化

初始化的流程指Bean创建完成后,AwareBeanPostProcessor 相关钩子方法的调用,可以完成Bean对象基本的初始化动作。

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
   // 一、调用 BeanNameAware 的 setBeanName() 方法
   // 二、调用 BeanFactoryAware 的 setBeanFactory() 方法
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   }
   else {
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      // 一、调用 ApplicationContextAware 的 setApplicationContext() 方法
      // 二、调用自定义的 BeanPostProcessor 的 postProcessBeforeInitialization() 方法
      // 三、调用 @PostConstruct 注解标注的方法
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
      // 一、调用 InitializingBean 的 afterPropertiesSet() 方法
      // 二、调用 <bean> 配置中 init-method 指向的方法 或 @Bean 注解中 initMethod 配置指向的方法
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
   catch (Throwable ex) {
      throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null),
            beanName, "Invocation of init method failed", ex);
   }
   if (mbd == null || !mbd.isSynthetic()) {
      // 调用自定义的 BeanPostProcessor 的 postProcessAfterInitialization() 方法
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}

initializeBean() 方法可以分解成四个部分:

  1. 通过 invokeAwareMethods() 方法完成对 BeanNameAwareBeanFactoryAware 的调用。
  2. 通过 applyBeanPostProcessorsBeforeInitialization() 方法完成对 ApplicationContextAwareBeanPostProcessor.postProcessBeforeInitialization()@PostConstruct 的调用。
  3. 通过 invokeInitMethods() 方法完成对 InitializingBeaninit-method 关联方法的调用。
  4. 通过 applyBeanPostProcessorsAfterInitialization() 完成对 BeanPostProcessor.postProcessAfterInitialization() 方法调用。

invokeAwareMethods() 方法里面,除了调用 BeanNameAwareBeanFactoryAware 外,还调用了 BeanClassLoaderAwaresetBeanClassLoader() 方法。

private void invokeAwareMethods(final String beanName, final Object bean) {
    if (bean instanceof Aware) {
        if (bean instanceof BeanNameAware) {
            ((BeanNameAware) bean).setBeanName(beanName);
        }
        if (bean instanceof BeanClassLoaderAware) {
            ClassLoader bcl = getBeanClassLoader();
            if (bcl != null) {
                ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
            }
        }
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}

这里,有一点需要注意的是,ApplicationContextAware 并没有在 invokeAwareMethods() 里面调用。而是在 applyBeanPostProcessorsBeforeInitialization() 通过调用 ApplicationContextAwareProcessorpostProcessBeforeInitialization() 方法实现的。 ApplicationContextAwareProcessor 的实现逻辑如下:

class ApplicationContextAwareProcessor implements BeanPostProcessor {

    .....

    @Override
    @Nullable
    public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
        AccessControlContext acc = null;

        if (System.getSecurityManager() != null &&
                (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
                        bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
                        bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
            acc = this.applicationContext.getBeanFactory().getAccessControlContext();
        }

        if (acc != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                invokeAwareInterfaces(bean);
                return null;
            }, acc);
        }
        else {
            invokeAwareInterfaces(bean);
        }

        return bean;
    }

    private void invokeAwareInterfaces(Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof EnvironmentAware) {
                ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
            }
            if (bean instanceof EmbeddedValueResolverAware) {
                ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
            }
            if (bean instanceof ResourceLoaderAware) {
                ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
            }
            if (bean instanceof ApplicationEventPublisherAware) {
                ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
            }
            if (bean instanceof MessageSourceAware) {
                ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
            }
            // 调用 ApplicationContextAware 的 setApplicationContext() 方法
            if (bean instanceof ApplicationContextAware) {
                ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
            }
        }
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }

}

ApplicationContextAwareProcessor 的实现里面,还调用了 EnvironmentAwareEmbeddedValueResolverAwareResourceLoaderAwareApplicationEventPublisherAwareMessageSourceAware 等钩子接口。而在 postProcessAfterInitialization() 未做任何处理,这使得在后面触发该方法调用时不会产生任何影响。

还有另外一个值得注意的地方是 @PostConstruct 也并未在 invokeInitMethods() 方法中调用,而是与 ApplicationContextAware 一样,使用 BeanPostProcessor 的方式实现,它对应的实现类是 InitDestroyAnnotationBeanPostProcessor,此类除了 BeanPostProcessor 接口外,还实现了 DestructionAwareBeanPostProcessor 接口,并在此接口定义的方法中完成了对 @PreDestroy 的处理。具体的实现如下:

public class InitDestroyAnnotationBeanPostProcessor
        implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
        try {
            // 调用 @PostConstruct
            metadata.invokeInitMethods(bean, beanName);
        }
        catch (InvocationTargetException ex) {
            throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
        }
        catch (Throwable ex) {
            throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
        try {
            // 调用 @PreDestroy
            metadata.invokeDestroyMethods(bean, beanName);
        }
        catch (InvocationTargetException ex) {
            String msg = "Destroy method on bean with name '" + beanName + "' threw an exception";
            if (logger.isDebugEnabled()) {
                logger.warn(msg, ex.getTargetException());
            }
            else {
                logger.warn(msg + ": " + ex.getTargetException());
            }
        }
        catch (Throwable ex) {
            logger.warn("Failed to invoke destroy method on bean with name '" + beanName + "'", ex);
        }
    }
}

applyBeanPostProcessorsBeforeInitialization() 方法里,除了ApplicationContextAware@PostConstruct 以外,主要是调用了 BeanPostProcessorpostProcessBeforeInitialization() 方法。

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
      throws Throwable {

   // 调用 InitializingBean 的 afterPropertiesSet() 方法
   boolean isInitializingBean = (bean instanceof InitializingBean);
   if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
      if (logger.isTraceEnabled()) {
         logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
      }
      if (System.getSecurityManager() != null) {
         try {
            AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
               ((InitializingBean) bean).afterPropertiesSet();
               return null;
            }, getAccessControlContext());
         }
         catch (PrivilegedActionException pae) {
            throw pae.getException();
         }
      }
      else {
         ((InitializingBean) bean).afterPropertiesSet();
      }
   }

   // 调用 <bean> 的 init-method 或 @Bean 的 initMethod 指定的方法
   if (mbd != null && bean.getClass() != NullBean.class) {
      String initMethodName = mbd.getInitMethodName();
      if (StringUtils.hasLength(initMethodName) &&
            !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.isExternallyManagedInitMethod(initMethodName)) {
         invokeCustomInitMethod(beanName, bean, mbd);
      }
   }
}

invokeInitMethods() 方法中,完成了如下两件事情:

  1. 调用 InitializingBeanafterPropertiesSet() 方法
  2. 调用 <bean>init-method@BeaninitMethod 指定的方法

最后的 applyBeanPostProcessorsAfterInitialization() 方法,不再多做介绍,与 applyBeanPostProcessorsBeforeInitialization() 类似,完成对 BeanPostProcessor.postProcessAfterInitialization() 方法的调用。

同样,在最后,我们使用时序图对初始化流程做下小结

在这里插入图片描述

Bean 销毁

Bean 销毁的流程全部在 DisposableBeanAdapterdestroy() 方法里面,流程比较简单,直接上代码

public void destroy() {
   // 调用 @PreDestroy
   if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
      for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
         processor.postProcessBeforeDestruction(this.bean, this.beanName);
      }
   }

   // 调用 DisposableBean 的 destroy() 方法
   if (this.invokeDisposableBean) {
      if (logger.isTraceEnabled()) {
         logger.trace("Invoking destroy() on bean with name '" + this.beanName + "'");
      }
      try {
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
               ((DisposableBean) this.bean).destroy();
               return null;
            }, this.acc);
         }
         else {
            ((DisposableBean) this.bean).destroy();
         }
      }
      catch (Throwable ex) {
         String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";
         if (logger.isDebugEnabled()) {
            logger.warn(msg, ex);
         }
         else {
            logger.warn(msg + ": " + ex);
         }
      }
   }

   // 调用 <bean> 的 destroy-method 或 @Bean 的 destroyMethod 指定的方法
   if (this.destroyMethod != null) {
      invokeCustomDestroyMethod(this.destroyMethod);
   }
   else if (this.destroyMethodName != null) {
      Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
      if (methodToInvoke != null) {
         invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
      }
   }
}

destroy() 方法的主要逻辑如下:

  1. 通过 InitDestroyAnnotationBeanPostProcessor 实现 DestructionAwareBeanPostProcessor 接口,完成对 @PreDestroy 标注方法的调用
  2. 调用 DisposableBeandestroy() 方法
  3. 调用 <bean>destroy-method@BeandestroyMethod 指定的方法

Bean销毁流程的时序图整理如下:
Bean销毁流程

Q码记
欢迎您扫一扫上面的微信公众号,订阅我的博客!

内容: 这个合成医疗保健数据集的创建是为了作为数据科学、机器学习和数据分析爱好者的宝贵资源。 灵感: 医疗保健数据通常很敏感,并受隐私法规的约束,因此难以访问以进行学习和实验。为了解决这一差距,我利用 Python 的 Faker 库生成了一个数据集,该数据集反映了医疗保健记录中常见的结构和属性。通过提供这些合成数据,我希望促进医疗保健分析领域的创新、学习和知识共享。 表格信息: 每列都提供有关患者、其入院情况和提供的医疗保健服务的特定信息,使此数据集适用于医疗保健领域的各种数据分析和建模任务。以下是数据集中每一列的简要说明 - 名字:此列表示与医疗保健记录关联的患者的姓名。 年龄:患者入院时的年龄,以年表示。 性:指示患者的性别,“男性”或“女性”。 血型:患者的血型,可以是常见的血型之一(例如,“A+”、“O-”等)。 医疗状况:此列指定了与患者相关的主要医疗状况或诊断,例如“糖尿病”、“高血压”、“哮喘”等。 入学日期:患者入住医疗机构的日期。 医生:在患者入院期间负责护理的医生的姓名。 医院:标识患者收治的医疗机构或医院。 保险提供商:此列指示患者的保险提供商,可以是多个选项之一,包括“Aetna”、“Blue Cross”、“Cigna”、“UnitedHealthcare”和“Medicare”。 账单金额:患者在入院期间为他们的医疗保健服务开具的账单金额。这表示为浮点数。 房间号:患者入院期间入住的房间号。 入场类型:指定入院类型,可以是“紧急”、“选择性”或“紧急”,以反映入院的情况。 出院日期:患者从医疗机构出院的日期,基于入院日期和实际范围内的随机天数。 药物:确定患者在入院期间开具或服用的药物。例子包括“阿司匹林”、“布洛芬”、“青霉素”、“扑热息痛”和“立普妥”。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值