springbean的生命周期_对Spring Bean生命周期的一些补充理解

a95a3f4cd5d83a9f789cf24414354d31.png

缘由

在之前我解析Spring IoC原理的文章,我顺带提到了Spring中的Bean的生命周期,但是当时我只是粗略地带过,而没有对必要的细节予以阐述。因此,在这篇文章,我会详细地针对Spring中Bean的生命周期再做一次详细的总结。

整体阶段

Spring中Bean的生命周期主要分为以下几个大阶段:

  • 实例化
  • 属性赋值
  • 初始化
  • 使用中
  • 销毁

下面分阶段详细讲解下

实例化

实例化是Bean生命周期的第一个阶段,在这一阶段,容器根据容器内已有的 BeanDefinition 生成 BeanWrapperBeanWrapper 是Spring用来操作对象属性的一个工具,使用它能够更加简单方便地操作将成为Bean的对象,此时应当已经生成了最上层的Bean对象,但此时并未进行依赖注入,还不是完整的Bean。

下面是代码的印证:

org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java

81be0f7985daa4b0216c609b4dfd1908.png

上面印证了在生成Bean的时候确实是依照BeanDefinition的,并且生成的是 BeanWrapper 类型

属性赋值

BeanWrapper 生成后,就进入了属性赋值阶段。如果说刚开始生成的 BeanWrapper 只是一个对象空壳,那么在该阶段则进行的是则是具体属性的注入。关键的依赖注入阶段应当是在该阶段完成的:

同样,我们深入源码看看,属性赋值阶段就是发生在上一段代码中 populateBean() 这个方法期间:

3761331bb73adf3e0c01759decf450f3.png

在这段代码中,主要发生的事情是决定注入的类型,这里分出了通过name和type进行注入。我们以更简单的byName注入为例,来看看具体是怎么注入的,我们进入 autowiredByName() 方法:(注意这里传入的newPvs就是属性值)

aad5e25d20ac519ce905665e13a83d51.png

可以看到这里遍历了每一个属性名,然后根据属性名获取新的Bean,然后将Bean装入带pvs中(属性集Map),这个就是最核心的依赖注入过程,这个 getBean() 让整体有了点递归的意味。那我们再回去,现在这里已经获取到了装入属性的集合,现在看他应当是确实注入到了我们的Bean中:

06abafe8318f6d54dc977a15f1b9219e.png

先看看这个,在我们通过依赖注入获取到pvs这个装满属性值的集合后,这里还进行了一次 BeanPostProcessor 处理,需要注意的是这里的这个处理是针对已装载的Bean的,而不是最终Bean的PostProcessor,这里的命名也揭示了这一点 pvsToUse 证明现在这些属性值已经确实可以投入使用了,现在我们回到正题:

在代码的末尾,执行了 applyPropertyValues() 这个方法,这个是最终赋值的函数,我们进去看看:

a41c594790d0fa3a942a50da0b6d85e9.png

这里,bw就是 BeanWrapper,mpvs就是处理完成的属性结合,通过了 setPropertyValues 方法直接将属性放入了bw中,属性赋值也就完成了(当然,这个方法的逻辑其实比较复杂,牵扯了很多异常处理和多情况,这里截取了最终的结果关键代码)

至此,属性已经通过BeanWrapper完全注入到了对象中

初始化

虽然属性注入已经完成,但是作为Bean,在此阶段才开始“初始化”,在Bean的属性注入完成后,我们可以选择对此时的Bean进行一些操作

f2818aaf2aaf628646152e7beeecb1d7.png

这段代码是通过Aware相关接口设置相关依赖,让Bean对象与Bean容器产生联系,并获得相应的容器资源。

9bcc55bd3a852030765a7188984c81b6.png

我们可以看到,在属性注入完后,调用了 initializeBean 这个方法,我们再去看看这个方法中的代码:

bf3f9c3314ea51d1633b7665ea898a2c.png

上面的代码说明了这里执行了 BeanPostProcessorsBeforeInitialization 方法,在此处进行了 BeanPostProcessor 前置处理

49d57e68b7e2c49a12ced566ce709c84.png

809a0e6c41d8d4fb37053345220c520f.png

这两个代码说明了继续按顺序执行了 init-methodBeanPostProcessor 后置处理。最终返回了Bean,此时的Bean已经可以被使用了

使用中

这里就是客户端来使用Bean了,略去

销毁

在Bean结束使用后,会依序调用 DisposableBeandestory 方法,然后是最后的自定义销毁方法 detory-method,用于在Bean销毁后进行一系列操作。当最后的操作结束时,Bean的一生也就结束了,可以,它这一生,没有白活2333!

由于这里的代码逻辑基本是和前面相仿的,并且简单许多,这里就不去探究了2333(其实是懒)

总结

整个Spring Bean的生命周期还是很壮阔的,这样去探究一番,在之后去理解和使用Spring Bean应该会有新的体会。当然,我这里只是过了重点代码和大体框架,细节的东西还有很多,因此其实距离真正地理解Bean在Spring IoC容器中的生存,还有很长的路要走。。。

这个图很好的描述了这个过程,应当记在心里:

64e9ce41c1127adfb9462b4fa2e0c1ff.png


(感谢这位知乎er的图)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值