Spring 执行顺序:Bean 的生命周期

回目录

代码:https://gitee.com/free/boot-order/tree/master/src/main/java/com/github/abel533/lifecycle

通过本例了解一个 Bean 中所有生命周期方法执行的顺序。

BeanLifecycle 实现了几乎全部方式的初始化和关闭方法,在当前例子中,执行顺序如下:

  1. @PostConstruct
  2. InitializingBean#afterPropertiesSet
  3. @Bean(initMethod)
  4. SmartLifecycle#isRunning = falsetrue时不会执行下面的 start)
  5. SmartLifecycle#start
  6. SmartLifecycle#isRunning = true (false 时不会执行下面的 stop)
  7. SmartLifecycle#stop
  8. @PreDestroy
  9. DisposableBean#destroy
  10. @Bean(destroyMethod)

第 0 个 @PostConstruct,在 InitDestroyAnnotationBeanPostProcessor 实现的 BeanPostProcessor#postProcessBeforeInitialization 方法中执行。

更早是在 AbstractAutowireCapableBeanFactory#initializeBean 中执行,代码如下(有删减):

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        //执行 0
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
    try {
        //执行 1 和 2
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
    }
    return wrappedBean;
}

第 1 和 2 在 AbstractAutowireCapableBeanFactory 类中,该类继承的 AbstractBeanFactory#createBean 方法中,按照 doCreateBean > initializeBean > invokeInitMethods 顺序调用,在 invokeInitMethods 方法中执行了初始化方法。代码如下(有删减):

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
        throws Throwable {
    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        if (System.getSecurityManager() != null) {
            try {
                AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                    //调用方法 1
                    ((InitializingBean) bean).afterPropertiesSet();
                    return null;
                }, getAccessControlContext());
            }
            catch (PrivilegedActionException pae) {}
        }
        else {
             //调用方法 1
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }

    if (mbd != null && bean.getClass() != NullBean.class) {
        String initMethodName = mbd.getInitMethodName();
        if (StringUtils.hasLength(initMethodName) &&
                !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                !mbd.isExternallyManagedInitMethod(initMethodName)) {
            //调用方法 2
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}

代码有删减,这里先调用 InitializingBean,然后是配置的 InitMethodName 对应的方法。

3 和 4 是先判断 isRunning,如果没有运行(false)在执行 start,这里是在 SpringApplication#refresh 后,层层调用,最终在 DefaultLifecycleProcessor 中执行,代码如下(有删减):

private void doStart(Map<String, ? extends Lifecycle> lifecycleBeans, String beanName, boolean autoStartupOnly) {
    Lifecycle bean = lifecycleBeans.remove(beanName);
    if (bean != null && bean != this) {
        //判断是否 SmartLifecycle 并且自动运行
        if (!bean.isRunning() &&
                (!autoStartupOnly || !(bean instanceof SmartLifecycle) || ((SmartLifecycle) bean).isAutoStartup())) {
            try {
                //调用方法
                bean.start();
            }
            catch (Throwable ex) {}
        }
    }
}

5 和 6 也在 DefaultLifecycleProcessor 中执行 doStop 方法,逻辑和上面类似,这里不贴了,此时的方法堆栈如下:

doStop:231, DefaultLifecycleProcessor (org.springframework.context.support)
access$300:53, DefaultLifecycleProcessor (org.springframework.context.support)
stop:377, DefaultLifecycleProcessor$LifecycleGroup (org.springframework.context.support)
stopBeans:210, DefaultLifecycleProcessor (org.springframework.context.support)
onClose:128, DefaultLifecycleProcessor (org.springframework.context.support)
doClose:1003, AbstractApplicationContext (org.springframework.context.support)
close:961, AbstractApplicationContext (org.springframework.context.support)
main:11, BeanApplication (com.github.abel533.lifecycle)

这里需要关注 AbstractApplicationContext#doClose,代码如下(有删减):

protected void doClose() {
    if (this.active.get() && this.closed.compareAndSet(false, true)) {
        // Stop all Lifecycle beans, to avoid delays during individual destruction.
        if (this.lifecycleProcessor != null) {
            //这里对应 6 的 stop
            this.lifecycleProcessor.onClose();
        }
        // Destroy all cached singletons in the context's BeanFactory.
        // 这里对应 7 的 @PreDestroy
        destroyBeans();
    }
}

7 最早调用该方法的地方见上面代码,这里和 @PostConstruct 类似,在 InitDestroyAnnotationBeanPostProcessor 实现的 DestructionAwareBeanPostProcessor#postProcessBeforeDestruction 方法中执行。

8 和 9 在 DisposableBeanAdapter 实现的 DisposableBean#destroy 中,代码如下(有删减):

@Override
public void destroy() {
    if (this.invokeDisposableBean) {
        try {
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
                    //执行方法 8
                    ((DisposableBean) this.bean).destroy();
                    return null;
                }, this.acc);
            }
            else {
                //执行方法 8
                ((DisposableBean) this.bean).destroy();
            }
        }
        catch (Throwable ex) {
        }
    }

    if (this.destroyMethod != null) {
        //执行方法 9
        invokeCustomDestroyMethod(this.destroyMethod);
    }
    else if (this.destroyMethodName != null) {
        Method methodToCall = determineDestroyMethod(this.destroyMethodName);
        if (methodToCall != null) {
            //执行方法 9
            invokeCustomDestroyMethod(methodToCall);
        }
    }
}

通过以上代码和分析可以了解 Bean 的整个生命周期了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring 上下文中的 Bean 生命周期Spring Bean 生命周期基本相同,但是 Spring 上下文中还包含了一些额外的生命周期方法: 1. BeanFactoryPostProcessor 的 postProcessBeanFactory() 方法:在 BeanFactory 实例化之后,调用所有 BeanFactoryPostProcessor 实现类的 postProcessBeanFactory() 方法,可以在此方法中对 BeanFactory 进行增强。 2. BeanPostProcessor 的 postProcessBeforeInstantiation() 方法:在实例化 Bean 对象之前,调用所有 BeanPostProcessor 实现类的 postProcessBeforeInstantiation() 方法,可以在此方法中修改 Bean 的实例化过程。 3. InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation() 方法:在实例化 Bean 对象之前,调用所有 InstantiationAwareBeanPostProcessor 实现类的 postProcessBeforeInstantiation() 方法,可以在此方法中修改 Bean 的实例化过程。 4. InstantiationAwareBeanPostProcessor 的 postProcessPropertyValues() 方法:在 Bean 对象属性注入完成后,调用所有 InstantiationAwareBeanPostProcessor 实现类的 postProcessPropertyValues() 方法,可以在此方法中修改 Bean 的属性值。 5. BeanPostProcessor 的 postProcessAfterInitialization() 方法:在自定义初始化方法执行后,调用所有 BeanPostProcessor 实现类的 postProcessAfterInitialization() 方法,可以在此方法中对 Bean 进行增强。 6. DisposableBean 的 destroy() 方法:在容器关闭时,调用所有实现了 DisposableBean 接口的 Bean 的 destroy() 方法,可以在此方法中完成 Bean 的销毁操作。 7. DestroyBean 的 destroy() 方法:在容器关闭时,调用所有配置了 destroy-method 属性的 Bean 的 destroy() 方法,可以在此方法中完成 Bean 的销毁操作。 需要注意的是,Spring 上下文中的 Bean 生命周期顺序可能会与 Spring Bean 生命周期顺序略有不同,因为 Spring 上下文中还包含了额外的生命周期方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

isea533

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值