spring-boot源码分析之beanFactory · 拾
前言
今天分享的refresh
是的最后三个方法:
destroyBeans
cancelRefresh
resetCommonCaches
这三个方法中,有两个位于catch
语句块,主要是用于refresh
方法运行异常时,清除已经构建的bean
和依赖的,另一个方法位于finally
语句块中,主要用于启动成功或失败后重置各类缓存。
refresh最后的晚餐
finishRefresh补充
在开始今天的内容之前,我们先对finishRefresh
做一个简单的补充。
finishRefresh
方法内部共调用了5
个方法,第一个方法就是情况Resource
的缓存,其内部就是将DefaultResourceLoader
的resourceCaches
属性置空,这个属性是class
和资源的map
集合。
第二个方法是初始化生命周期处理器,其内部就是往beanFactory
中注册一个名字为lifecycleProcessor
的单例bean
。并将这个bean
赋值给当前容器的lifecycleProcessor
。
第三个方法就是获取到第二个方法赋值的lifecycleProcessor
,并执行它的onRefresh
方法。
从第二个方法那里可以看出来,生命周期处理器的类型为DefaultLifecycleProcessor
,所以这里的的onRefresh
方法内部实现如下:
onRefresh
方法内部调用了 startBean
方法,它的内部实现如下:
根据bebug
结果,最终还是会进入forEach
的if
条件中,虽然autoStartOnly
是true
,但后面的条件是成立的,因此下面的for
循环也会被执行,最终会 LifecycleGroup
的start
方法:
LifecycleGroup
最终会调用bean
的生命周期的start
(就是我们昨天分析的createWebServer
方法那里注册的两个生命周期bean
)
后面两个方法都很简单,一个是推送事件,这里推送的是ContextRefreshedEvent
事件;另一个方法是将当前容器添加到LiveBeansView
的applicationContexts
容器中,也就不展开说明了。
剩余方法
今天要分析的是剩余的三个方法,这三个方法有两个在catch
中,也就是用了处理异常信息的,另一个个在finally
中,也就是无论如何都会被执行的,下面我们就详细展开看一下。
destroyBeans
这个从名字就可以看出它的作用了,是的,就是销毁已经实例化完成的bean
,也就是说如果refresh
方法发生异常,会先销毁所有的bean
在destroySingletons
方法内部,它首先调用了父类的destroySingletons
方法,最终在父类的方法内部调用destroySingletons
以递归的方式销毁bean
和bean
的依赖,具体流程如下:
cancelRefresh
发生异常后取消容器刷新操作,这里只是将容器的激活状态改为false
resetCommonCaches
这个方法始终会被执行,它的作用就是清理各种缓存以及classLoader
,其中ReflectionUtils
清理的是和反射相关的缓存,AnnotationUtils
清理的是和注解相关的缓存,ResolvableType
清理的是和解析类型相关的缓存,CachedIntrospectionResults.clearClassLoader
清理的是类加载器的相关缓存。
至此,refresh
方法算是彻底分享完了,run
方法中剩余的方法,由于之前已经分析过了,所以这里就不过多赘述了,后面就该花时间把最近一段时间的内容好好梳理下,然后该补充的再补充下(比如上周五的内容)。
总结
说实话我是没想到剩余的三个方法这么简单,总体内容都没有昨天finishRefresh
的补充内容多,不过也能想明白,毕竟今天内容就是catch
和finally
语句块的方法,也不会有太核心的内容。
今天分享完毕后,剩余的工作就是查漏补缺和知识点梳理了,原本想着经过梳理run
方法会发现有集中初始化的代码,但是截止到现在都没找到,至少不像我之前手写的web
服务器那种,不过现在感觉似乎已经对spring boot
的bean
的完整初始化过程有了一点点懵懂的认知,我想等我梳理完最近分析的代码,这一团迷雾一定会被揭开……
好了,今天就先到这里吧,各位小伙伴,晚安哟!
- END -