spring-boot源码分析之beanFactory · 拾

云中志

共 1929字,需浏览 4分钟

 ·

2021-09-17 16:34

前言

今天分享的refresh是的最后三个方法:

  • destroyBeans
  • cancelRefresh
  • resetCommonCaches

这三个方法中,有两个位于catch语句块,主要是用于refresh方法运行异常时,清除已经构建的bean和依赖的,另一个方法位于finally语句块中,主要用于启动成功或失败后重置各类缓存。

refresh最后的晚餐

finishRefresh补充

在开始今天的内容之前,我们先对finishRefresh做一个简单的补充。

finishRefresh方法内部共调用了5个方法,第一个方法就是情况Resource的缓存,其内部就是将DefaultResourceLoaderresourceCaches属性置空,这个属性是class和资源的map集合。

第二个方法是初始化生命周期处理器,其内部就是往beanFactory中注册一个名字为lifecycleProcessor的单例bean。并将这个bean赋值给当前容器的lifecycleProcessor

第三个方法就是获取到第二个方法赋值的lifecycleProcessor,并执行它的onRefresh方法。

从第二个方法那里可以看出来,生命周期处理器的类型为DefaultLifecycleProcessor,所以这里的的onRefresh方法内部实现如下:

onRefresh方法内部调用了 startBean方法,它的内部实现如下:

根据bebug结果,最终还是会进入forEachif条件中,虽然autoStartOnlytrue,但后面的条件是成立的,因此下面的for循环也会被执行,最终会 LifecycleGroupstart方法:

LifecycleGroup最终会调用bean的生命周期的start(就是我们昨天分析的createWebServer方法那里注册的两个生命周期bean

后面两个方法都很简单,一个是推送事件,这里推送的是ContextRefreshedEvent事件;另一个方法是将当前容器添加到LiveBeansViewapplicationContexts容器中,也就不展开说明了。

剩余方法

今天要分析的是剩余的三个方法,这三个方法有两个在catch中,也就是用了处理异常信息的,另一个个在finally中,也就是无论如何都会被执行的,下面我们就详细展开看一下。

destroyBeans

这个从名字就可以看出它的作用了,是的,就是销毁已经实例化完成的bean,也就是说如果refresh方法发生异常,会先销毁所有的bean

destroySingletons方法内部,它首先调用了父类的destroySingletons方法,最终在父类的方法内部调用destroySingletons以递归的方式销毁beanbean的依赖,具体流程如下:

cancelRefresh

发生异常后取消容器刷新操作,这里只是将容器的激活状态改为false

resetCommonCaches

这个方法始终会被执行,它的作用就是清理各种缓存以及classLoader,其中ReflectionUtils清理的是和反射相关的缓存,AnnotationUtils清理的是和注解相关的缓存,ResolvableType清理的是和解析类型相关的缓存,CachedIntrospectionResults.clearClassLoader清理的是类加载器的相关缓存。

至此,refresh方法算是彻底分享完了,run方法中剩余的方法,由于之前已经分析过了,所以这里就不过多赘述了,后面就该花时间把最近一段时间的内容好好梳理下,然后该补充的再补充下(比如上周五的内容)。

总结

说实话我是没想到剩余的三个方法这么简单,总体内容都没有昨天finishRefresh的补充内容多,不过也能想明白,毕竟今天内容就是catchfinally语句块的方法,也不会有太核心的内容。

今天分享完毕后,剩余的工作就是查漏补缺和知识点梳理了,原本想着经过梳理run方法会发现有集中初始化的代码,但是截止到现在都没找到,至少不像我之前手写的web服务器那种,不过现在感觉似乎已经对spring bootbean的完整初始化过程有了一点点懵懂的认知,我想等我梳理完最近分析的代码,这一团迷雾一定会被揭开……

好了,今天就先到这里吧,各位小伙伴,晚安哟!

- END -


浏览 17
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报