通过AbstractApplicationContext#refresh()提供了在加载完配置文件后的启动过程。以SpringBoot的Web环境来看启动过程(文末有spring容器的启动过程及区别)
1.prepareRefresh():由于在此时还没有加载servlet容器,所以servletContext=null,servletConfig=null,还没有进行初始化propertySource,添加了几个ApplicationListeners。
2.obtainFreshBeanFactory():创建BeanFactory,即DefaultListableBeanFactory
3.prepareBeanFactory():对DefaultListableBeanFactory进行属性填充。如:添加类加载器,添加BeanPostProcessor等等。
4.postProcessBeanFactory():在上面prepareBeanFactory()公共的之后,提供子类的特殊处理,注册特殊的后处理器,此处为ServletWebServerApplicationContext的具体实现。
5.invokeBeanFactoryPostProcessors():主要是扫描包,注册成BeanDefinition,对类配置的信息解析成BeanDefinition的属性。然后执行实现了BeanFactoryPostProcessor接口的bean的postProcessBeanFactory()方法。
对于BeanDefinitionRegistryPostProcessor类型的BeanFactoryPostProcessor,执行postProcessBeanDefinitionRegistry
ConfigurationWarningsApplicationContextInitializer类型的processor,检查包名是否异常
获取类型为BeanDefinitionRegistryPostProcessor并且是PriorityOrdered优先排序类型的beanDefinition
上面获取postProcessorNames的具体实现如下
调用刚获取到的currentRegistryProcessor列表中的bean的postProcessBeanDefinitionRegistry()方法
获取到启动类
对启动类开始进行解析,包装成SourceClass,开始解析
获取到需要扫描的包信息,开始进行解析
解析是否有includeFilters,excludeFilters,lazyInit等属性,解析basePackage,basePackageClasses配置,如果没有,则根据启动类的包名获取,最终获得需要扫描的包。
解析包下所有beanDefinition,遍历并逐个解析。 如果实现了AnnotatedBeanDefinition接口,解析是否有lazy,Primary,DependsOn,Role,Description等注解并对beanDefinition进行相应属性设置。 检查是否在beanDefinitionMap中,如果不存在则将beanDefinition注册到beanDefinitionMap中。
对获取到的包下的beanDefinition进行遍历处理。处理是否import,ImportResource,Bean注解,处理实现的接口。
处理完BeanDefinitionRegistryPostProcessor类型的bean之后,处理之前注册的处理器,前两个处理器没做任何处理,第三个处理器ConfigurationClassPostProcessor,对目前加载的所有的beanDefinition进行处理。如果是启动类,生成代理类并替换原来的beanClass
获取实现了BeanFactoryPostProcessor接口的类,去除了上面已经解析过的internalConfigurationAnnotationProcessor,根据是否排序进行分类,然后按照PriorityOrdered,Ordered,nonOrdered以此执行。
6.registerBeanPostProcessors():获取实现了BeanPostProcessor的bean,并根据是否实现order接口进行排序,并按顺序注册到beanPostProcessors中。
7.initMessageSource():
8.initApplicationEventMulticaster():注册事件广播器
9.onRefresh():获取ServletWebServerFactory(tomcatServletWebServerFactory),创建TomcatWebServer,然后initServletPropertySources
创建TomcatWebServer之后获取需要初始化的servlet,filter
将servlet添加到servletContext中
将filter添加到servletContext中
10.registerListeners():在事件广播器中注册监听器,注册监听器name,如果earlyApplicationEvents存在,则广播事件。
11.finishBeanFactoryInitialization():实例化bean
先进行实例化之前的操作,再实例化bean。
如果有实现InstantiationAwareBeanPostProcessor, 则执行postProcessBeforeInstantiation
根据实例化策略进行实例化(这里是cglib)包装成BeanWrapper
实例化之后执行后处理
执行postProcessProperties
属性设置,在AutowiredAnnotationBeanPostProcessor中进行依赖注入
是否实现BeanNameAware,BeanClassLoaderAware,BeanFactoryAware等接口
init之前
调用自定义的init方法,在InitDestroyAnnotationBeanPostProcessor中处理
如果实现了InitializingBean,执行afterPropertiesSet()方法
然后执行init之后的方法
12.finishRefresh():主要做的事情是启动tomcat,并发布事件
逐个listener去匹配事件
以下为spring环境启动与web环境启动的相同和不同:
1.prepareRefresh():区别在于initPropertySources()的实现不同,spring上下文为AnnotationConfigApplicationContext,web上下文AnnotationConfigServletWebServerApplicationContext
2.obtainFreshBeanFactory():相同
3.prepareBeanFactory():相同
4.postProcessBeanFactory():spring使用的AbstractApplicationContext的默认处理,没有提供实现,web提供了实现注册了特殊的处理器
5.invokeBeanFactoryPostProcessors():相同
6.registerBeanPostProcessors():相同
7.initMessageSource():相同
8.initApplicationEventMulticaster():相同
9.onRefresh():spring什么都没做,使用的AbstractApplicationContext的默认实现,web提供了创建web容器的过程
10.registerListeners():相同
11.finishBeanFactoryInitialization():相同
12.finishRefresh():spring主要做的事情是发布事件,web容器多了一步启动web容器
综上:web环境和spring环境启动容器流程基本相同,spring默认使用AbstractApplicationContext的实现,web多了properties解析,注册特殊处理器,创建webServer和启动webServer的过程。