Spring Bean的生命周期


一、引言

  要想理解Spring框架,那么Spring Bean的生命周期就是必須要了解的一環,關於Spring Bean的生命周期,就是一個Bean在IOC容器中從創建到銷毀的過程,下面就開始梳理一下一個Bean的創建過程。

二、生命周期概要流程

  簡單的來說,一個Bean的生命周期分為四個階段:

  1、實例化(Instantiation)

  2、屬性設置(populate)

  3、初始化(Initialization)

  4、銷毀(Destruction)

如下圖:

  具體邏輯位於AbstractAutowireCapableBeanFactory類doCreateBean方法中,代碼較多,只放出了重要的部分,如下:

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        BeanWrapper instanceWrapper = null;

        if (instanceWrapper == null) {
            //實例化
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

        try {
            //屬性賦值
            this.populateBean(beanName, mbd, instanceWrapper);
            //初始化
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        } catch (Throwable var18) {
            //...
        }

        try {
            //注冊銷毀回調接口
            this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
            return exposedObject;
        } catch (BeanDefinitionValidationException var16) {
            //...
        }
    }

   上面是的步實例化、屬性賦值、初始化都是Spring容器啟動時的步驟,銷毀是在容器關閉時的操作,容器銷毀時會調用容器的close()方法去銷毀容器。

三、對生命周期的擴展

  Spring在創建Bean的時候不僅僅只創建了一個我們設置的Bean,還可以在創建Bean的時候對它進行很多的擴展,總的來說有以下幾類:

  1、BeanPostProcessor接口

  2、InstantiationAwareBeanPostProcessor接口

  3、Aware類型的接口

  4、生命周期類型接口

  其中1和2是作用於所有Bean的接口,3和4是作用於單個Bean的接口。BeanPostProcessor是初始化時的后置處理器,InstantiationAwareBeanPostProcessor是實例化時的后置處理器,Aware類型的接口如BeanNameAware、BeanFactoryAware等需要Bean自己去實現,生命周期類型接口如InitializingBean、DisposableBean。

  加上這些擴展,現在上面的圖可以變成下面這樣了:

   接下來看詳細的源碼,剛剛我們提到的實例化、屬性賦值、初始化這三個步驟都在doCreateBean方法中,那么在這個方法之前有什么操作嗎:

    //createBean方法里面調用了doCreateBean
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        Object beanInstance;
        try {
            //這個里面調用了InstantiationAwareBeanPostProcessor的前置方法postProcessBeforeIns
            beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
        } catch (Throwable var10) {
            //...
        }
        //...
        try {
            //這里調用了doCreateBean
            beanInstance = this.doCreateBean(beanName, mbdToUse, args);

            return beanInstance;
        } catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
            //...
        } catch (Throwable var8) {
            //...
        }
    }

    //resolveBeforeInstantiation方法里面調用了這個方法
    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        Iterator var3 = this.getBeanPostProcessors().iterator();

        while(var3.hasNext()) {
            BeanPostProcessor bp = (BeanPostProcessor)var3.next();
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                //調用了InstantiationAwareBeanPostProcessor的前置方法postProcessBeforeInstantiation
                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                if (result != null) {
                    return result;
                }
            }
        }

        return null;
    }

  在調用完InstantiationAwareBeanPostProcessor的前置方法之后接下來進入doCreateBean方法,首先會執行createBeanInstance(beanName, mbd, args)進行實例化,然后進入populateBean(beanName, mbd, instanceWrapper)方法進行屬性賦值,看一下這一部分代碼還有沒有別的操作:

    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        if (bw == null) {
            //...
        } else {
            if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
                Iterator var4 = this.getBeanPostProcessors().iterator();

                while(var4.hasNext()) {
                    BeanPostProcessor bp = (BeanPostProcessor)var4.next();
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                        
                        //執行InstantiationAwareBeanPostProcessor的后置方法postProcessAfterInstantiation
                        if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                            return;
                        }
                    }
                }
            }
            if (hasInstAwareBpps) {
                Iterator var9 = this.getBeanPostProcessors().iterator();
                while(var9.hasNext()) {
                    BeanPostProcessor bp = (BeanPostProcessor)var9.next();
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                        
                        //執行執行InstantiationAwareBeanPostProcessor的postProcessProperties
                        PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
                        if (pvsToUse == null) {
                            
                            ////執行執行InstantiationAwareBeanPostProcessor的postProcessPropertyValues(該方法已廢棄,不建議使用)
                            pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        }
                    }
                }
            }

        }
    }

  通過源碼可以看出InstantiationAwareBeanPostProcessor的幾個方法分別在實例化的前后完成,然后進行屬性賦值,接下來就是實例化initializeBean(beanName, exposedObject, mbd),我們來看一下:

    //該方法位於AbstractAutowireCapableBeanFactory類中,這段代碼很簡單,不像其他部分還添加了很多其他操作,這塊一看就明白了,就不把BeanPostProcessor、InitializingBean等具體的方法列出來了
    protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(() -> {
                //invokeAwareMethods方法執行實現的Aware接口
                this.invokeAwareMethods(beanName, bean);
                return null;
            }, this.getAccessControlContext());
        } else {
            //和上面的一樣,執行實現的Aware類型的接口
            this.invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            //這個方法里面執行了BeanPostProcessor的postProcessBeforeInitialization方法
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        }

        try {
            //執行了InitializingBean的afterPropertiesSet方法和自定義的init-method方法
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
        }

        if (mbd == null || !mbd.isSynthetic()) {
            //這個方法里面執行了BeanPostProcessor的postProcessAfterInitialization方法
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

  關於Aware類型的接口這里要說一下,可能你會奇怪按照我上面的那個類去找invokeAwareMethods(beanName, bean)方法會是下面這種情況:

    private void invokeAwareMethods(String beanName, Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof BeanNameAware) {
                ((BeanNameAware)bean).setBeanName(beanName);
            }

            if (bean instanceof BeanClassLoaderAware) {
                ClassLoader bcl = this.getBeanClassLoader();
                if (bcl != null) {
                    ((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);
                }
            }

            if (bean instanceof BeanFactoryAware) {
                ((BeanFactoryAware)bean).setBeanFactory(this);
            }
        }

    }

  為什么只有這三個Aware類型的接口,明明還有其他好幾種啊,比如EnvironmentAware、EmbeddedValueResolverAware等,這是什么它們的容器不同,AbstractAutowireCapableBeanFactory使用的容器是BeanFactory,其他幾種是ApplicationContext 添加的擴展接口,如:

    //ApplicationContextAwareProcessor中實現的接口如下
    private void invokeAwareInterfaces(Object bean) {
        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);
        }

        if (bean instanceof ApplicationContextAware) {
            ((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
        }

    }

  到這一步初始化也完成了,至於銷毀時在容器關閉時執行容器的close方法,close方法中會執行destroy方法銷毀所有的Bean:

    //銷毀Bean的方法
    public void destroy() {
        if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
            Iterator var1 = this.beanPostProcessors.iterator();

            while(var1.hasNext()) {
                //其實這里也有個銷毀時的處理器,實現了BeanPostProcessor,在執行銷毀方法前執行postProcessBeforeDestruction方法
                DestructionAwareBeanPostProcessor processor = (DestructionAwareBeanPostProcessor)var1.next();
                processor.postProcessBeforeDestruction(this.bean, this.beanName);
            }
        }

        if (this.invokeDisposableBean) {

            try {
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged(() -> {
                        //執行DisposableBean的destroy方法
                        ((DisposableBean)this.bean).destroy();
                        return null;
                    }, this.acc);
                } else {
                    //同上,執行DisposableBean的destroy方法
                    ((DisposableBean)this.bean).destroy();
                }
            } catch (Throwable var3) {
                //...
            }
        }

        if (this.destroyMethod != null) {
            //如果存在指定的銷毀方法就執行,即destroy-method指定的方法
            this.invokeCustomDestroyMethod(this.destroyMethod);
        } else if (this.destroyMethodName != null) {
            //...
        }

    }

  到這里我們已經看完了一個Bean從實例化到銷毀的所有步驟。

四、總結

  總的來說Spring Bean的生命周期就是四大步驟,實例化 -> 屬性賦值 ->初始化 ->銷毀,其他的操作都是對這四個步驟的擴展。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM