Spring Bean的生命周期

要彻底搞清楚 Spring 的生命周期,首先要把这四个阶段牢牢记住。实例化和属性赋值对应构造方法setter 方法的注入,初始化和销毁是用户能自定义扩展的两个阶段。

  1. 实例化->Instantiation
  2. 属性赋值->Populate
  3. 初始化->Initialization
  4. 销毁->Destruction

实例化 -> 属性赋值 -> 初始化 -> 销毁

1、影响多个 Bean 的接口

实现了这些接口的 Bean 会切入到多个 Bean 的生命周期中。正因为如此,这些接口的功能非常强大,Spring 内部扩展也经常使用这些接口,例如自动注入以及 AOP 的实现都和他们有关。

  • InstantiationAwareBeanPostProcessor
  • BeanPostProcessor

这两兄弟可能是 Spring 扩展中最重要的两个接口!InstantiationAwareBeanPostProcessor 作用于实例化阶段的前后,BeanPostProcessor 作用于初始化阶段的前后。如图:
image.png
其中 InstantiationAwareBeanPostProcessor 继承自 BeanPostProcessor 是 Spring 非常重要的拓展接口
1、postProcessBeforeInstantiation 调用时机为 bean 实例化(Instantiation)之前 如果返回了 bean 实例, 则会替代原来正常通过 target bean 生成的 bean 的流程. 典型的例如 aop 返回 proxy 对象. 此时 bean 的执行流程将会缩短, 只会执行 BeanPostProcessor#postProcessAfterInitialization 接口完成初始化。
2、postProcessAfterInstantiation 调用时机为 bean 实例化(Instantiation)之后和任何初始化(Initialization)之前。
3、postProcessProperties 调用时机为 postProcessAfterInstantiation 执行之后并返回 true, 返回的 PropertyValues 将作用于给定 bean 属性赋值。Spring 5.1 之后出现以替换@Deprecated 标注的 postProcessPropertyValues
4、postProcessPropertyValues 已经被标注@Deprecated,后续将会被 postProcessProperties 取代。
进入执行流程
步骤 1 :InstantiationAwareBeanPostProcessor 的触发入口 AbstractAutowireCapableBeanFactory #createBean 开始。

/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
*
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {

    // 省略......
    try {
        /**
        * 注释1. InstantiationAwareBeanPostProcessor#postProcessorsBeforeInstantiation触发入口
        */
        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 {
        /**
        * 注释2. postProcessAfterInstantiation、postProcessProperties 触发入口
        * 主要逻辑都在doCreateBean()方法中,
        * 方法中包含了实例化、属性赋值、初始化过程。逻辑很清晰
        * 这三个方法与三个生命周期阶段一一对应,非常重要
        */
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isTraceEnabled()) {
            logger.trace("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
        // A previously detected exception with proper bean creation context already,
        // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
        throw ex;
    } catch (Throwable ex) {
        throw new BeanCreationException(
            mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
}

步骤 2:注释 1 中,跟进 AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation, 分析 postProcessorsBeforeInstantiation 执行时机 :

/** 注释1 代码进入后执行InstantiationAwareBeanPostProcessor#ostProcessBeforeInstantiation方法*/
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // Make sure bean class is actually resolved at this point.
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            Class<?> targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
                /**
                * 注释3:回调beanPostProcessorsBeforeInstantiation实例化,如果返回bean非null则直接执行
                * 不为空null就直接返回了而不执行doCreateBean()方法了,而该方法是创建Bean对象的方法
                * beanPostProcessorsAfterInitialization进行实例初始化
                */
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    /** 注释4 */
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

/**注释3 代码跟进*/
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            /**
            * 注释5:只要其中一个postProcessBeforeInstantiation返回实例bean即结束回调,
            * 这个bean将会直接返回给bean容器管理
            */
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
            if (result != null) {
                return result;
            }
        }
    }
    return null;
}

/** 注释4 代码跟进*/
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    throws BeansException {
    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        /**注释6 */
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

可以看到,postProcessBeforeInstantiation 在 doCreateBean 之前调用,也就是在 bean 实例化之前调用的,英文源码注释解释道该方法的返回值会替换原本的 Bean 作为代理,这也是 Aop 等功能实现的关键点。

代码说明:

  1. 注释 5 中,如果 postProcessBeforeInstantiation 方法返回了 Object 是 null;那么就直接返回,调用 doCreateBean 方法();
  2. 注释 5 中,如果 postProcessBeforeInstantiation 返回不为 null;说明修改了 bean 对象;然后这个时候就立马执行 postProcessAfterInitialization 方法(注意这个是初始化之后的方法,也就是通过这个方法实例化了之后,直接执行初始化之后的方法;中间的实例化之后 和 初始化之前都不执行);
  3. 注释 6 中,在调用 postProcessAfterInitialization 方法时候如果返回 null;那么就直接返回,调用 doCreateBean 方法();(初始化之后的方法返回了 null,那就需要调用 doCreateBean 生成对象了)
  4. 在调用 postProcessAfterInitialization 时返回不为 null;那这个 bean 就直接返回给 ioc 容器了初始化之后的操作是这里面最后一个方法了;

步骤 2:跟进 AbstractAutowireCapableBeanFactory#doCreateBean, 分析 postProcessAfterInstantiation、postProcessProperties 执行时机 :

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

    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        /**  注释7 实例化阶段! */
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // 省略......
    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
        /** 注释8 依据bean definition 完成bean属性赋值 */
        populateBean(beanName, mbd, instanceWrapper);
        /** 注释9 执行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;
}

这三个方法与三个生命周期阶段一一对应,非常重要

  1. createBeanInstance() -> 实例化(注释 7)
  2. populateBean() -> 属性赋值(注释 8)
  3. initializeBean() -> 初始化(注释 9)

注释 8 中,继续跟进 AbstractAutowireCapableBeanFactory#populateBean

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

    // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    // state of the bean before properties are set. This can be used, for example,
    // to support styles of field injection.
    boolean continueWithPropertyPopulation = true;
    // InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()
    /**
    * 注释10:满足两个要求:
    * 1、BeanDefinition为应用程序bean,而非基础框架bean信息。
    * 2、注册过InstantiationAwareBeanPostProcessor类型接口,上文有提到这个标志位。
    * 3、注册了多个接口时,只要其中一个postProcessAfterInstantiation返回false,即停止后续执行。
    */
    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;
                }
            }
        }
    }

    // 忽略后续的属性赋值操作代码
}

可以看到该方法在属性赋值方法内,但是在真正执行赋值操作之前。其返回值为 boolean,返回 false 时可以阻断属性赋值阶段(continueWithPropertyPopulation = false;)
关于 BeanPostProcessor 执行阶段的源码穿插在下文 Aware 接口的调用时机分析中,因为部分 Aware 功能的就是通过他实现的!只需要先记住 BeanPostProcessor 在初始化前后调用就可以了。

2、只调用一次的接口

这一大类接口的特点是功能丰富,常用于用户自定义扩展。
第二大类中又可以分为两类:

  1. Aware 类型的接口
  2. 生命周期接口

Aware 类型的接口的作用就是让我们能够拿到 Spring 容器中的一些资源。基本都能够见名知意,Aware 之前的名字就是可以拿到什么资源,例如 BeanNameAware 可以拿到 BeanName,以此类推。调用时机需要注意:所有的 Aware 方法都是在初始化阶段之前调用的!
Aware 接口众多,这里同样通过分类的方式帮助大家记忆。
Aware 接口具体可以分为两组,至于为什么这么分,详见下面的源码分析。如下排列顺序同样也是 Aware 接口的执行顺序,能够见名知意的接口不再解释。
Aware Group1

  1. BeanNameAware
  2. BeanClassLoaderAware
  3. BeanFactoryAware

Aware Group2

  1. EnvironmentAware
  2. EmbeddedValueResolverAware (这个知道的人可能不多,实现该接口能够获取 Spring EL 解析器,用户的自定义注解需要支持 spel 表达式的时候可以使用,非常方便。)
  3. ApplicationContextAware(ResourceLoaderAware\ApplicationEventPublisherAware\MessageSourceAware) 这几个接口可能让人有点懵,实际上这几个接口可以一起记,其返回值实质上都是当前的 ApplicationContext 对象,因为 ApplicationContext 是一个复合接口,如下:
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
}

这里涉及常问的问题,ApplicationContext 和 BeanFactory 的区别,可以从 ApplicationContext 继承的这几个接口入手,除去 BeanFactory 相关的两个接口(ListableBeanFactory, HierarchicalBeanFactory)就是 ApplicationContext 独有的功能,这里不详细说明。

Aware 调用时机源码分析

详情如下,忽略了部分无关代码。代码位置就是我们上文提到的 initializeBean 方法详情,这也说明了 Aware 都是在初始化阶段之前调用的!

// 注释9 代码进入 调用初始化阶段
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {

    // 注释11 这里调用的是Group1中的三个Bean开头的Aware
    invokeAwareMethods(beanName, bean);

    Object wrappedBean = bean;

    /**
    * 这里调用的是Group2中的几个Aware,
    * 而实质上这里就是前面所说的BeanPostProcessor的调用点!
    * 也就是说与Group1中的Aware不同,这里是通过BeanPostProcessor(ApplicationContextAwareProcessor)实现的。
    */
    /** 注释12 */
    wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    /** 注释13 下文即将介绍的InitializingBean调用点 */
    invokeInitMethods(beanName, wrappedBean, mbd);
    /** 注释14 BeanPostProcessor的另一个调用点*/
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

    return wrappedBean;
}

/**注释11 代码进入 */
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) {
            ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
        }
        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
        }
    }
}

注释 11 代码进入后,可以看到并不是所有的 Aware 接口都使用同样的方式调用。Bean××Aware 都是在代码中直接调用的。
而 ApplicationContext 相关的 Aware 都是通过 applyBeanPostProcessorsBeforeInitialization 来调用 BeanPostProcessor#postProcessBeforeInitialization()实现的。感兴趣的可以自己看一下 ApplicationContextAwareProcessor 这个类的源码,就是判断当前创建的 Bean 是否实现了相关的 Aware 方法,如果实现了会调用回调方法将资源传递给 Bean。
至于 Spring 为什么这么实现,应该没什么特殊的考量。也许和 Spring 的版本升级有关。基于对修改关闭,对扩展开放的原则,Spring 对一些新的 Aware 采用了扩展的方式添加。
BeanPostProcessor 的调用时机也能在这里体现,包围住 invokeInitMethods 方法,也就说明了在初始化阶段的前后执行。
关于 Aware 接口的执行顺序,其实只需要记住第一组在第二组执行之前就行了。每组中各个 Aware 方法的调用顺序其实没有必要记,有需要的时候点进源码一看便知。

简单的两个生命周期接口

至于剩下的两个生命周期接口就很简单了,实例化和属性赋值都是 Spring 帮助我们做的,能够自己实现的有初始化和销毁两个生命周期阶段。

  1. InitializingBean 对应生命周期的初始化阶段,在上面源码的 invokeInitMethods(beanName, wrappedBean, mbd);方法中调用。
    有一点需要注意,因为 Aware 方法都是执行在初始化方法之前,所以可以在初始化方法中放心大胆的使用 Aware 接口获取的资源,这也是我们自定义扩展 Spring 的常用方式。
    除了实现 InitializingBean 接口之外还能通过注解或者 xml 配置的方式指定初始化方法,至于这几种定义方式的调用顺序其实没有必要记。因为这几个方法对应的都是同一个生命周期,只是实现方式不同,我们一般只采用其中一种方式。
  2. DisposableBean 类似于 InitializingBean,对应生命周期的销毁阶段,以 ConfigurableApplicationContext#close()方法作为入口,实现是通过循环取所有实现了 DisposableBean 接口的 Bean 然后调用其 destroy()方法 。感兴趣的可以自行跟一下源码。

扩展阅读: BeanPostProcessor 注册时机与执行顺序

注册时机

我们知道 BeanPostProcessor 也会注册为 Bean,那么 Spring 是如何保证 BeanPostProcessor 在我们的业务 Bean 之前初始化完成呢?请看我们熟悉的 refresh()方法的源码,省略部分无关代码:

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {

        try {
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            // 所有BeanPostProcesser初始化的调用点
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            initMessageSource();

            // Initialize event multicaster for this context.
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            onRefresh();

            // Check for listener beans and register them.
            registerListeners();

            // Instantiate all remaining (non-lazy-init) singletons.
            // 所有单例非懒加载Bean的调用点
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            finishRefresh();
        }

}

可以看出,Spring 是先执行 registerBeanPostProcessors()进行 BeanPostProcessors 的注册,然后再执行 finishBeanFactoryInitialization 初始化我们的单例非懒加载的 Bean。

执行顺序

BeanPostProcessor 有很多个,而且每个 BeanPostProcessor 都影响多个 Bean,其执行顺序至关重要,必须能够控制其执行顺序才行。关于执行顺序这里需要引入两个排序相关的接口:PriorityOrdered、Ordered

  • PriorityOrdered 是一等公民,首先被执行,PriorityOrdered 公民之间通过接口返回值排序
  • Ordered 是二等公民,然后执行,Ordered 公民之间通过接口返回值排序
  • 都没有实现是三等公民,最后执行

在以下源码中,可以很清晰的看到 Spring 注册各种类型 BeanPostProcessor 的逻辑,根据实现不同排序接口进行分组。优先级高的先加入,优先级低的后加入。

// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 首先,加入实现了PriorityOrdered接口的BeanPostProcessors,顺便根据PriorityOrdered排了序
String[] postProcessorNames =
    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
        processedBeans.add(ppName);
    }
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();

// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 然后,加入实现了Ordered接口的BeanPostProcessors,顺便根据Ordered排了序
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
    if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
        processedBeans.add(ppName);
    }
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();

// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 最后加入其他常规的BeanPostProcessors
boolean reiterate = true;
while (reiterate) {
    reiterate = false;
    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    for (String ppName : postProcessorNames) {
        if (!processedBeans.contains(ppName)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
            reiterate = true;
        }
    }
    sortPostProcessors(currentRegistryProcessors, beanFactory);
    registryProcessors.addAll(currentRegistryProcessors);
    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    currentRegistryProcessors.clear();
}// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 首先,加入实现了PriorityOrdered接口的BeanPostProcessors,顺便根据PriorityOrdered排了序
String[] postProcessorNames =
    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
        processedBeans.add(ppName);
    }
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();

// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 然后,加入实现了Ordered接口的BeanPostProcessors,顺便根据Ordered排了序
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
    if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
        processedBeans.add(ppName);
    }
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();

// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 最后加入其他常规的BeanPostProcessors
boolean reiterate = true;
while (reiterate) {
    reiterate = false;
    postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    for (String ppName : postProcessorNames) {
        if (!processedBeans.contains(ppName)) {
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
            reiterate = true;
        }
    }
    sortPostProcessors(currentRegistryProcessors, beanFactory);
    registryProcessors.addAll(currentRegistryProcessors);
    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    currentRegistryProcessors.clear();
}

根据排序接口返回值排序,默认升序排序,返回值越低优先级越高。

/**
* Useful constant for the highest precedence value.
* @see java.lang.Integer#MIN_VALUE
*/
int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;

/**
* Useful constant for the lowest precedence value.
* @see java.lang.Integer#MAX_VALUE
*/
int LOWEST_PRECEDENCE = Integer.MAX_VALUE;}

PriorityOrdered、Ordered 接口作为 Spring 整个框架通用的排序接口,在 Spring 中应用广泛,也是非常重要的接口。

总结

Spring Bean 的生命周期分为四个阶段和多个扩展点。扩展点又可以分为影响多个 Bean 和影响单个 Bean。整理如下:

四个阶段

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

多个扩展点

  • 影响多个 Bean
    • BeanPostProcessor
    • InstantiationAwareBeanPostProcessor
  • 影响单个 Bean
    • Aware
      • Aware Group1
        • BeanNameAware
        • BeanClassLoaderAware
        • BeanFactoryAware
      • Aware Group2
        • EnvironmentAware
        • EmbeddedValueResolverAware
        • ApplicationContextAware(ResourceLoaderAware\ApplicationEventPublisherAware\MessageSourceAware)
    • 生命周期
      • InitializingBean
      • DisposableBean
  1. 如果实现了 BeanFactoryPostProcessor 接口,那么在容器启动的时候,该接口中的 postProcessBeanFactory 方法可以修改 Bean 中元数据中的信息。该方法是在实例化对象之前执行
  2. 如果实现了 InstantiationAwareBeanPostProcessor 接口,那么在实例化 Bean 对象之前会调用postProcessBeforeInstantiation方法,该方法如果返回的不为 null 则会直接调用 postProcessAfterInitialization 方法,而跳过了 Bean 实例化后及初始化前的相关方法,如果返回 null 则正常流程,postProcessAfterInstantiation在实例化成功后执行,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是 null。因为它的返回值是决定要不要调用 postProcessPropertyValues 方法的其中一个因素,因为还有一个因素是 mbd.getDependencyCheck();如果该方法返回 false,并且不需要 check,那么 postProcessPropertyValues 就会被忽略不执行;如果返回 true, postProcessPropertyValues 就会被执行,postProcessPropertyValues用来修改属性,在初始化方法之前执行。
  3. 如果实现了 Aware 相关的结果,那么相关的 set 方法会在初始化之前执行。
  4. 如果实现了 BeanPostProcessor 接口,那么该接口的方法会在实例化后的初始化方法前后执行。
  5. 如果实现了 InitializingBean 接口则在初始化的时候执行 afterPropertiesSet
  6. 如果指定了 init-method 属性则在初始化的时候会执行指定的方法。
  7. 如果指定了@PostConstruct 则在初始化的时候会执行标注的方法。
  8. 到此对象创建完成
  9. 当对象需要销毁的时候。
  10. 如果实现了 DisposableBean 接口会执行 destroy 方法
  11. 如果指定了 destroy-method 属性则会执行指定的方法
  12. 如果指定了@PreDestroy 注解则会执行标注的方法

至此,Spring Bean 的生命周期介绍完毕。

参考

Spring Bean 的生命周期(详细)
Spring Bean 的生命周期(Spring5)
一文读懂 Spring Bean 的生命周期

https://alicharles.oss-cn-hangzhou.aliyuncs.com/static/images/mp_qrcode.jpg
文章目录
  1. 1、影响多个 Bean 的接口
  2. 2、只调用一次的接口
    1. Aware 调用时机源码分析
    2. 简单的两个生命周期接口
    3. 注册时机
    4. 执行顺序
  3. 总结
  4. 参考