一、引言
要想理解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的生命周期就是四大步驟,實例化 -> 屬性賦值 ->初始化 ->銷毀,其他的操作都是對這四個步驟的擴展。