几个直击灵魂的Spring拷问(二)

Spring Bean的生命周期一直是Spring面试热点问题,网上的解答也有很多种,但是仅凭死记硬背而不去从源码上理解是很难回答得好这个问题的,因此这里先提纲挈领的给出答案和流程图,然后在列出源码+注释,帮助大家更好的理解这个问题。

一、四个关键步骤:


spring bean的生命周期有四个:实例化 -> 属性赋值 -> 初始化 -> 销毁

  • 实例化 Instantiation
  • 属性赋值 Populate
  • 初始化 Initialization
  • 销毁 Destruction

主要的代码逻辑都在AbstractAutowireCapableBeanFactory#doCreateBean()方法中,省略中间过程就是如下:

//AbstractAutowireCapableBeanFactory#doCreateBean,已忽略了无关代码
protected Object doCreateBean(final String beanName, 
      final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {

   // Instantiate the bean.
   BeanWrapper instanceWrapper = null;
   if (instanceWrapper == null) {
       // 实例化阶段!
      instanceWrapper = createBeanInstance(beanName, mbd, args);
   }

   // Initialize the bean instance.
   Object exposedObject = bean;
   try {
       // 属性赋值阶段!
      populateBean(beanName, mbd, instanceWrapper);
       // 初始化阶段!
      exposedObject = initializeBean(beanName, exposedObject, mbd);
   }
}

至于销毁,是在容器关闭时调用的,详见ConfigurableApplicationContext#close()

二、详细步骤


如果问及bean的生命周期,仅仅回答上面的四个步骤还是远远不够的,Spring生命周期相关的常用扩展点非常多,这些也很关键,如果想要回答一个近满分的Spring bean生命周期,我这里总结出一个比较细致的流程,在关键流程的下面挂上小的扩展点细节,这样的流程就比较全面了,四个步骤的具体说明如下:

1. 实例化 Instantiation

从一个成熟的 BeanDefinion 开始生命周期,实例化前后会执行InstantiationAwareBeanPostProcessor的方法:

  • for 循环调用所有的InstantiationAwareBeanPostProcessor接口# postProcessBeforeInstantiation()方法。(执行的主要是AbstractAutoProxyCreator这个类中的方法,决定是否要进行AOP代理)
  • 调用 createBeanInstance() 方法进行实例化,推断构造函数通过反射来创建对象,默认是采用的无参构造函数。
  • 继续 for 循环调用所有的InstantiationAwareBeanPostProcessor接口# postProcessAfterInstantiation()方法。

上面三个过程createBeanInstance()方法是实例化方法,环绕这个方法的上下分别是InstantiationAwareBeanPostProcessor接口的两个 before 和 after 方法,InstantiationAwareBeanPostProcessor 继承自 BeanPostProcessor接口,扩展出来两个方法专门用于实例化的时候调用。

2.属性赋值 Populate

属性注入主要在方法populateBean()中实现,可以理解为调用setter方法完成属性注入。这儿分别完成了 Spring 的自动注入和精确注入(手动注入),最终都通过调用 InstantiationAwareBeanPostProcessor 接口的 postProcessProperties()方法来实现属性注入。

3.初始化 Initialization

初始化流程主要是按照Spring的规则配置一些初始化的方法(例如@PostConstruct注解)。这里也穿插了BeanPostProcessor接口的两个重要方法,流程细节如下:

  • invokeAwareMethods(),执行 Aware 接口中的方法,只有三个:BeanNameAware,BeanClassLoaderAware,BeanFactoryAware,分别是获取Bean的名字,获取加载这个Bean的类加载器 和 获取当前的 BeanFactory
  • for 循环遍历 BeanPostProcessor 接口的postProcessBeforeInitialization()方法,这里有两个重要的实现类:1、ApplicationContextAware 类完成Aware接口方法的执行,2、CommonAnnotationBeanPostProcessor 类完成 @PostConstructor 方法的执行。
  • 调用 invokeInitMethods() 方法去完成初始化方法执行,先判断是否实现了对应的生命周期回调的接口(InitializingBean),如果实现了接口,先调用接口中的afterPropertiesSet方法。之后在判断是否提供了initMethod,也就是在XML中的Bean标签中提供了init-method属性。
  • for 循环遍历 BeanPostProcessor 接口的postProcessAfterInitialization()方法,这里就是等Spring的bean充分装配好以后,进行aop的代理。

4.销毁 Destruction

Bean销毁回调,执行顺序如下:被 @PostConstruct所标记的方法、InitializingBean 接口中的afterPropertiesSet() 方法、Bean 标签中的 init()方法。

三、扩展点说明


Bean本身的四个生命周期比较好理解,但是由于穿插了几大扩展点以后,变得复杂了起来,如果每次都去死记硬背的话很容易凌乱,下面就其中的关键扩展点进行梳理和总结,下面一一来说:

1、直接实现BeanPostProcessor接口

最简单的后置处理器,直接实现了BeanPostProcessor接口,这种后置处理器只能在初始化的前后阶段执行。

public interface BeanPostProcessor {

   // 初始化前执行的方法
   @Nullable
   default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      return bean;
 }    
    
   // 初始化后执行的方法
   default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      return bean;
}

2、直接实现InstantiationAwareBeanPostProcessor接口

在第一种后置处理的基础上进行了一层扩展,可以在Bean的实例化阶段前后执行,这个过程比BeanPostProcessor的声明周期要更提前了一些。

/**
   继承了BeanPostProcessor,额外提供了两个方法用于在实例化前后的阶段执行
   因为实例化后紧接着就要进行属性注入,所以这个接口中还提供了一个属性注入的方法
**/
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
 
   // 实例化前执行
   default Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
      return null;
   }
 
   // 实例化后置
   default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
      return true;
   }
    
   // 属性注入
   default PropertyValues postProcessPropertyValues(
         PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
      return pvs;
   }
}

当然除了以上两类后置处理器,还有Spring自己专门用的 SmartInstantiationAwareBeanPostProcessor处理器,它实现了三个关键方法:推断bean类型,推断构造函数以及解决循环依赖的,但是一般不在bean的生命周期中去讨论。

3.实现Aware接口

Aware类型的接口的作用就是让我们能够拿到Spring容器中的一些资源。基本都能够见名知意,Aware之前的名字就是可以拿到什么资源,例如BeanNameAware可以拿到BeanName,以此类推。但是Aware调用的时机是有讲究的,都是在初始化阶段之前调用!这样做的目的是因为,初始化可能会依赖Aware接口提供的状态,比如下面这段代码:

@Component
public class A implements InitializingBean, ApplicationContextAware {
 
    ApplicationContext applicationContext;
 
    @Override
    public void afterPropertiesSet() throws Exception {
        // 初始化方法需要用到ApplicationContextAware提供的ApplicationContext
        System.out.println(applicationContext);
    }
 
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

因为Aware方法都是执行在初始化方法之前,所以可以在初始化方法中放心大胆的使用Aware接口获取的资源,这也是我们自定义扩展Spring的常用方式。

4.两个生命周期接口

  • InitializingBean 对应生命周期的初始化阶段,在源码的 invokeInitMethods(beanName, wrappedBean, mbd);方法中调用。
  • DisposableBean 类似于InitializingBean,对应生命周期的销毁阶段,以ConfigurableApplicationContext#close()方法作为入口

在讨论Bean的初始化的时候经常会碰到下面这个问题,@PostConstruct, afterPropertiesSet跟XML中配置的init-method方法的执行顺序。@PostConstruct实际上是在postProcessBeforeInitialization方法中处理的,严格来说它不属于初始化阶段调用的方法,所以这个方法是最先调用的。

于是乎把上面的扩展点+关键四步骤结合起来,在一张图里面来看,就是如下流程细节:

Spring bean 完整生命周期

关键源码阅读

下面就把Spring设计生命周期的源码贴出来,加上关键性注释,理解了以后方能完全消化吸收。

#AbstractAutowireCapableBeanFactory#createBean()

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

        RootBeanDefinition mbdToUse = mbd;
        
        // 第一步:解析BeanDefinition中的beanClass属性
        Class resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }
    
        try {
            // 第二步:处理lookup-method跟replace-method,判断是否存在方法的重载
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            // 第三步<关键>:判断这个类在之后是否需要进行AOP代理
            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 {
            // <关键>开始创建Bean
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            return beanInstance;
        }
        catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
        }
    }

AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation,实例化前的关键扩展,决定是否进行AOP代理。返回了bean则直接短路,无需初始化,不返回则继续走生命周期的剩余流程。

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // 不是合成类,并且有实例化后置处理器。这个判断基本上恒成立
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            // 获取这个BeanDefinition的类型
            Class targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
                // 这里执行的主要是AbstractAutoProxyCreator这个类中的方法,决定是否要进行AOP代理
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                // 这里执行了一个短路操作,如果在这个后置处理中直接返回了一个Bean
                // 那么后面相关的操作就不会执行了,只会执行一个AOP的代理操作
                if (bean != null) {
                    // 虽然这个Bean被短路了,意味着不需要经过后面的初始化阶段,
                    // 但是如果需要代理的话,还是要进行AOP代理,这个地方的短路操作
                    // 只是意味着我们直接在后置处理器中提供了一个准备充分的的Bean,
                    // 这个Bean不需要进行初始化,但需不需要进行代理,
                    // 仍然由AbstractAutoProxyCreator的applyBeanPostProcessorsBeforeInstantiation方法决定。
                    // 在这个地方还是要调用一次Bean的初始化后置处理器保证Bean被完全的处理完
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        // bean != null基本会一直返回false,所以beforeInstantiationResolved这个变量也会一直为false
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

AbstractAutowireCapableBeanFactory#doCreateBean,最最关键的代码段,包含了三个核心流程:实例化、属性注入和初始化。

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

        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            // 第一步:单例情况下,看factoryBeanInstanceCache这个缓存中是否有
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            // 第二步<关键>:这里创建对象
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        final Object bean = instanceWrapper.getWrappedInstance();
        Class beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    // 第三步:后置处理器处理
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    // 省略异常处理
                }
                mbd.postProcessed = true;
            }
        }
        
        // 循环引用相关,源码阅读阶段再来解读这段代码,暂且就关注以下后置处理器的调用时机
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            // 第四步:调用后置处理器,早期曝光一个工厂对象
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        Object exposedObject = bean;
        try {
            // 第五步<关键>:属性注入
            populateBean(beanName, mbd, instanceWrapper);
            // 第六步<关键>:初始化
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        }
        catch (Throwable ex) {
            if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                throw (BeanCreationException) ex;
            }
            else {
                // 省略异常处理
            }
        }

        if (earlySingletonExposure) {
            Object earlySingletonReference = getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                }
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                    for (String dependentBean : dependentBeans) {
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    if (!actualDependentBeans.isEmpty()) {
                        // 省略异常处理
                    }
                }
            }
        }

        try {
            // 第七步:注册需要销毁的Bean,放到一个需要销毁的Map中(disposableBeans)
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            // 省略异常处理
        }

        return exposedObject;
    }

AbstractAutowireCapableBeanFactory#createBeanInstance,通过反射来创建对象,具体采用哪个构造器反射,Spring会调用一个后置处理器来推断构造函数。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        // 获取到解析后的beanClass
        Class beanClass = resolveBeanClass(mbd, beanName);
        
        // 忽略异常处理
        Supplier instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }
        
        // 获取工厂方法,用于之后创建对象 
        if (mbd.getFactoryMethodName() != null) {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        // 原型情况下避免多次解析
        boolean resolved = false;
        boolean autowireNecessary = false;
        if (args == null) {
            synchronized (mbd.constructorArgumentLock) {
                if (mbd.resolvedConstructorOrFactoryMethod != null) {
                    resolved = true;
                    autowireNecessary = mbd.constructorArgumentsResolved;
                }
            }
        }
        if (resolved) {
            if (autowireNecessary) {
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                return instantiateBean(beanName, mbd);
            }
        }

        // 跟后置处理器相关,我们主要关注这行代码
        Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
                mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
            return autowireConstructor(beanName, mbd, ctors, args);
        }

        // Preferred constructors for default construction?
        ctors = mbd.getPreferredConstructors();
        if (ctors != null) {
            return autowireConstructor(beanName, mbd, ctors, null);
        }

        // 默认使用无参构造函数创建对象
        return instantiateBean(beanName, mbd);
    }

AbstractAutowireCapableBeanFactory#populateBean,主要关注两个个方法,postProcessAfterInstantiation 这个负责进行实例化后的后置处理,postProcessProperties 这个方法会将之前通过postProcessMergedBeanDefinition方法找到的注入点,在这一步进行注入。

    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        if (bw == null) {
            if (mbd.hasPropertyValues()) {
                // 省略异常
            }
            else {
                return;
            }
        }

        boolean continueWithPropertyPopulation = true;

        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    // <关键>主要判断之后是否需要进行属性注入
                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {            
                        continueWithPropertyPopulation = false;
                        break;
                    }
                }
            }
        }

        if (!continueWithPropertyPopulation) {
            return;
        }

        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
        
        // 自动注入模型下,找到合适的属性,在后续方法中再进行注入
        if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
            // Add property values based on autowire by name if applicable.
            if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }
            // Add property values based on autowire by type if applicable.
            if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }
            pvs = newPvs;
        }
        
        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

        PropertyDescriptor[] filteredPds = null;
        if (hasInstAwareBpps) {
            if (pvs == null) {
                pvs = mbd.getPropertyValues();
            }
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    // <关键>精确注入下,在这里完成属性注入
                    PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                    // 一般不会进行这个方法
                    if (pvsToUse == null) {
                        if (filteredPds == null) {
                            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                        }
                        pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvsToUse == null) {
                            return;
                        }
                    }
                    pvs = pvsToUse;
                }
            }
        }
        if (needsDepCheck) {
            if (filteredPds == null) {
                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            }
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }

        if (pvs != null) {
            // XML配置,或者自动注入,会将之前找到的属性在这里进行注入
            applyPropertyValues(beanName, mbd, bw, pvs);
        }
    }

AbstractAutowireCapableBeanFactory#initializeBean,实例化这里每一步都是重点,作用都写在注释里了。

    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            // 第一步<关键>:执行aware接口中的方法,需要主要的是,不是所有的Aware接口都是在这步执行了
            invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            // 第二步<关键>:完成Aware接口方法的执行,以及@PostConstructor,@PreDestroy注解的处理
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }

        try {
            // 第三步<关键>:完成初始化方法执行
            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()) {
            // 第四步<关键>:完成AOP代理
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }
 
 

主要参考


  1. 请别再问Spring Bean的生命周期了!
  2. 如果你每次面试前都要去背一篇Spring中Bean的生命周期,请看完这篇文章
  3. Spring官网阅读(九)Spring中Bean的生命周期(上)
  4. Spring官网阅读(十)Spring中Bean的生命周期(下)

你可能感兴趣的:(几个直击灵魂的Spring拷问(二))