Spring系列之 IOC容器的创建
Spring系列之 IOC容器的创建
ShioSpring系列之 IOC容器的创建
我叫Spring,是一个万千程序员朋友们每天都在手心把玩的小宝贝。上次为各位朋友们介绍了我是如何通过SpringApplication.run(String[])
启动,今天为大家详细介绍第四个大阶段“填充容器”,也就是面试中最频繁问到的步骤“自动装配Bean”。
这一阶段共分为12个小步骤:
第一步,我会通过prepareRefresh
方法,在已有的“系统环境”基础上,准备Servlet相关的环境。其他的环境配置在第二个大阶段“环境准备”中就已经注册完成了,具体可以参考合集的第二集。这一步还包括对ServletConfig.InitParams
进行赋值,然后通过validateRequiredProperties
方法验证是否有必填的环境变量。最终,完成监听器和事件初始化之后,环境准备就完成了。
第二步和第三步,由于Spring Boot选择了ServletWebServerApplicationContext
作为容器,在之前的步骤已经构造好了BeanFactory
,因此obtainFreshBeanFactory
中不进行任何处理。不过值得注意的是,对于原生的Spring来说,每次执行obtainFreshBeanFactory
时,都会重新加载“Bean定义”BeanDefinition
。而在准备容器prepareBeanFactory
过程中,主要准备“类加载器”BeanClassLoader
、“表达式解析器”BeanExpressionResolver
以及两个“Bean后置处理器”!同时会注册一些“特殊Bean”和“系统级Bean”,比如容器本身BeanFactory
和ApplicationContext
,将它们放入“特殊对象池”和“单例池”中。
第四步,我会通过postProcessBeanFactory
方法,对BeanFactory
进行额外设置或修改,同时也注册与Servlet相关的一些特殊Bean。
第五步,开始执行我非常核心的invokeBeanFactoryPostProcessors
方法。首先,我会逐一执行在第三个大阶段“容器创建”中注册的BeanFactoryPostProcessor
实例,其中最主要的就是用来加载所有“Bean定义”的“配置处理器”ConfigurationClassPostProcessor
。通过它加载所有@Configuration
配置类,并通过CassPathBeanDefinitionScanner
中的doScan
方法扫描每个类,将所有扫描出来的“Bean定义”都放到“Bean定义池”BeanDefinitionMap
中。
第六步,我要通过registerBeanPostProcessors
方法,检索所有的“Bean后置处理器”,同时根据指定的order
为它们进行排序,然后放入“后置处理器池”beanPostProcessors
中。每一个“Bean后置处理器”都会在Bean初始化之前和之后分别执行对应的逻辑。
第七步和第八步,涉及到两个关键的Bean注册:一个是用于Web服务器的Bean,另一个是用于自定义广播事件的Bean。我体内默认的服务器是Tomcat,接下来通过getWebServer
方法构造一个Tomcat对象,同时通过start
方法进行启动,这样我体内的Web服务器就开始运行了。
第九步,通过registerListeners
方法,在Bean中查找所有的“监听器Bean”,将它们注册到ApplicationEventMulticaster
中。
第十步,这一步就是通过finishBeanFactoryInitialization
方法完成剩余的初始化工作。这个过程较为复杂,需要详细理解可以参考合集的第一集。
第十一步,Bean
生成之后会放入“单例池”singletonObjects
中。
第十二步,这最后一步我会通过finishRefresh
方法完成容器的最终刷新,当然,在容器关闭时也会自动调用对应的stop
方法。接着发布一个“容器刷新完成”的事件之后,整个12步的“填充容器”就完成了。
如果你喜欢这期视频的话,请一定记得长按点赞按钮,求各位朋友们一个三连鼓励,给我一些信心坚持制作下去。