上文我们介绍了spring boot是如何启动的,那么bean的自动装配发生在第四个大阶段容器填充
自动装配bean供分为12个小步骤
第一步,通过prepareRefresh方法,在已有的系统环境上准备servlet相关的环境Environment,其他的环境配置在第二个大阶段“环境准备”中已经注册完成了;通过初始化属性资源initServletPropertySources方法对servlet初始化参数servContextletInitParams和servletConfigInitParams进行赋值
然后检验是否有必填的环境变量
最后,完成监听器和事件初始化之后环境准备就完成了
第二步和第三步,通过obtainFreshBeanFactory和prepareBeanFactory方法,在获取容器同时再使用BeanFactory之前进行一些准备工作,由于spring boot选择了servletWebServerApplicationContext作为容器,在之前已经构造好beanfactory了,所以obtainFreshBeanFactory中不进行任何处理,不过对于原始的spring来说很多情况下会选择ClassPathXmlApplicationContext作为容器,每次执行obtainFreshBeanFactory时会通过它的refreshBeanfactory方法重新构造beanfactory,并重新加载bean定义
在prepareBeanFactory方法中,主要准备类加载器BenaClassLoader,表达式解析器BeanExpressionReslover,配置文件处理器propertyEditorRegisrar等系统级处理器,以及两个bean后置处理器,用来解析aware接口的ApplicationContextAwareProcessor,用来处理自定义监听器注册和销毁的ApplicationListenerDetector,同时会注册一些特出bean和系统bean,比如容器本身beanFactory和ApplicationContext,系统环境environment,系统属性systemproperties,将它们放入特殊对象池和单例池中
第四步,通过postProcessorBeanFactory方法对beanFactory进行额外的设置或修改,这里主要定义
第五步,执行核心的invokeBeanFactoryPostProcessor方法,首先会逐一执行在第三个大阶段“容器准备”,注册的“各种beanFactory后置处理器”beanFactoryProcessor,其中最主要的就是用来加载所有“bean定义”的配置处理器configurationClassPostProcessor,通过它架子啊所有@Configuration配置类,同时检索指定的bean扫描路径componentScans,然后通过bean扫描器ClassPathBeanDefinitionScans中的doScan方法扫描每个类,将所有扫描出来的“bean定义”都放在bean定义池beanDefinitionMap中,同样也会扫描所有加了@bean,@import等注解的类和方法,将它们对应的bean定义放在bean定义池,这样后续可以通过这些bean定义进行bean的构造
第六步**,通过registerBeanPostProcessor方法检索所有的bean后置处理器
第七步和第八步:通过initMessageSource和initApplicationEventMulticaster方法从单力池中获取两个实用的bean放在applicationcontext中,一个是用于国际化“messageSource”的bean
另一个是用于自定义广播事件,名为initApplicationEventMulticaster的bean,有了它就可以通过publishEvent方法进行事件的发布了
第九步,通过onRefresh构造并启动web服务器,先查找实现了servletwebServerFactory这个接口的服务器bean,默认的是tomcat,接下来通过getWebServer方法构造一个tomcat对象并通过start方法启动,这样web服务器就开始启动了
第十步:registerListener方法在bean中查找所有的“监听器bean”,将它们注册到第八步中构造的消息广播器initApplicationEventMulticaste
第十一步,通过finishBeanFactoryinitialization方法来生产所有的bean,整体分为构造对象,填充属性,初始化实例,注册销毁四个步骤,bean生成之后会放入单例池,singletonObjects中
第十二步,通过finishRefresh方法构造并注册“生命周期管理器“lifeCycleProcessor,同时会调用所有实现了lifeCycle接口的bean中的start方法,当然在容器关闭时也会调用stop方法,接着发布容器刷新完成事件 ,整个12步 填充容器就完成了