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 的整個生命週期了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章