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

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码记
欢迎您扫一扫上面的微信公众号,订阅我的博客!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值