Spring Bean的生命周期
卫旗 人气:0一、引言
要想理解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的生命周期就是四大步骤,实例化 -> 属性赋值 ->初始化 ->销毁,其他的操作都是对这四个步骤的扩展。
加载全部内容