缘由
在之前我解析Spring IoC原理的文章,我顺带提到了Spring中的Bean的生命周期,但是当时我只是粗略地带过,而没有对必要的细节予以阐述。因此,在这篇文章,我会详细地针对Spring中Bean的生命周期再做一次详细的总结。
整体阶段
Spring中Bean的生命周期主要分为以下几个大阶段:
- 实例化
- 属性赋值
- 初始化
- 使用中
- 销毁
下面分阶段详细讲解下
实例化
实例化是Bean生命周期的第一个阶段,在这一阶段,容器根据容器内已有的 BeanDefinition
生成 BeanWrapper
, BeanWrapper
是Spring用来操作对象属性的一个工具,使用它能够更加简单方便地操作将成为Bean的对象,此时应当已经生成了最上层的Bean对象,但此时并未进行依赖注入,还不是完整的Bean。
下面是代码的印证:
org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
上面印证了在生成Bean的时候确实是依照BeanDefinition的,并且生成的是 BeanWrapper
类型
属性赋值
BeanWrapper
生成后,就进入了属性赋值阶段。如果说刚开始生成的 BeanWrapper
只是一个对象空壳,那么在该阶段则进行的是则是具体属性的注入。关键的依赖注入阶段应当是在该阶段完成的:
同样,我们深入源码看看,属性赋值阶段就是发生在上一段代码中 populateBean()
这个方法期间:
在这段代码中,主要发生的事情是决定注入的类型,这里分出了通过name和type进行注入。我们以更简单的byName注入为例,来看看具体是怎么注入的,我们进入 autowiredByName()
方法:(注意这里传入的newPvs就是属性值)
可以看到这里遍历了每一个属性名,然后根据属性名获取新的Bean,然后将Bean装入带pvs中(属性集Map),这个就是最核心的依赖注入过程,这个 getBean()
让整体有了点递归的意味。那我们再回去,现在这里已经获取到了装入属性的集合,现在看他应当是确实注入到了我们的Bean中:
先看看这个,在我们通过依赖注入获取到pvs这个装满属性值的集合后,这里还进行了一次 BeanPostProcessor
处理,需要注意的是这里的这个处理是针对已装载的Bean的,而不是最终Bean的PostProcessor,这里的命名也揭示了这一点 pvsToUse
证明现在这些属性值已经确实可以投入使用了,现在我们回到正题:
在代码的末尾,执行了 applyPropertyValues()
这个方法,这个是最终赋值的函数,我们进去看看:
这里,bw就是 BeanWrapper
,mpvs就是处理完成的属性结合,通过了 setPropertyValues
方法直接将属性放入了bw中,属性赋值也就完成了(当然,这个方法的逻辑其实比较复杂,牵扯了很多异常处理和多情况,这里截取了最终的结果关键代码)
至此,属性已经通过BeanWrapper完全注入到了对象中
初始化
虽然属性注入已经完成,但是作为Bean,在此阶段才开始“初始化”,在Bean的属性注入完成后,我们可以选择对此时的Bean进行一些操作
这段代码是通过Aware相关接口设置相关依赖,让Bean对象与Bean容器产生联系,并获得相应的容器资源。
我们可以看到,在属性注入完后,调用了 initializeBean
这个方法,我们再去看看这个方法中的代码:
上面的代码说明了这里执行了 BeanPostProcessorsBeforeInitialization
方法,在此处进行了 BeanPostProcessor
前置处理
这两个代码说明了继续按顺序执行了 init-method
和 BeanPostProcessor
后置处理。最终返回了Bean,此时的Bean已经可以被使用了
使用中
这里就是客户端来使用Bean了,略去
销毁
在Bean结束使用后,会依序调用 DisposableBean
的 destory
方法,然后是最后的自定义销毁方法 detory-method
,用于在Bean销毁后进行一系列操作。当最后的操作结束时,Bean的一生也就结束了,可以,它这一生,没有白活2333!
由于这里的代码逻辑基本是和前面相仿的,并且简单许多,这里就不去探究了2333(其实是懒)
总结
整个Spring Bean的生命周期还是很壮阔的,这样去探究一番,在之后去理解和使用Spring Bean应该会有新的体会。当然,我这里只是过了重点代码和大体框架,细节的东西还有很多,因此其实距离真正地理解Bean在Spring IoC容器中的生存,还有很长的路要走。。。
这个图很好的描述了这个过程,应当记在心里:
(感谢这位知乎er的图)