Spring容器启动流程

通过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的具体实现。

web容器的实现

5.invokeBeanFactoryPostProcessors():主要是扫描包,注册成BeanDefinition,对类配置的信息解析成BeanDefinition的属性。然后执行实现了BeanFactoryPostProcessor接口的bean的postProcessBeanFactory()方法。

对BeanFactoryPostProcessor进行分类

对于BeanDefinitionRegistryPostProcessor类型的BeanFactoryPostProcessor,执行postProcessBeanDefinitionRegistry

SharedMetadataReaderFactoryContextInitializer类型的实现
SharedMetadataReaderFactoryContextInitializer类型的实现
org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory

ConfigurationWarningsApplicationContextInitializer类型的processor,检查包名是否异常

ConfigurationWarningsApplicationContextInitializer类型的实现

获取类型为BeanDefinitionRegistryPostProcessor并且是PriorityOrdered优先排序类型的beanDefinition

优先排序的

上面获取postProcessorNames的具体实现如下

获取优先排序的beanDefinition的过程
获取优先排序的beanDefinition的过程

调用刚获取到的currentRegistryProcessor列表中的bean的postProcessBeanDefinitionRegistry()方法

对优先排序的进行优先处理

获取到启动类

优先排序bean的逻辑

对启动类开始进行解析,包装成SourceClass,开始解析

获取到需要扫描的包信息,开始进行解析

解析是否有includeFilters,excludeFilters,lazyInit等属性,解析basePackage,basePackageClasses配置,如果没有,则根据启动类的包名获取,最终获得需要扫描的包。

对启动类的配置进行解析,以获得最终的需要扫描的包和类

解析包下所有beanDefinition,遍历并逐个解析。  如果实现了AnnotatedBeanDefinition接口,解析是否有lazy,Primary,DependsOn,Role,Description等注解并对beanDefinition进行相应属性设置。   检查是否在beanDefinitionMap中,如果不存在则将beanDefinition注册到beanDefinitionMap中。

将包下的类包装成beanDefinition,并解析类的配置

对获取到的包下的beanDefinition进行遍历处理。处理是否import,ImportResource,Bean注解,处理实现的接口。

处理完BeanDefinitionRegistryPostProcessor类型的bean之后,处理之前注册的处理器,前两个处理器没做任何处理,第三个处理器ConfigurationClassPostProcessor,对目前加载的所有的beanDefinition进行处理。如果是启动类,生成代理类并替换原来的beanClass

生成代理类

获取实现了BeanFactoryPostProcessor接口的类,去除了上面已经解析过的internalConfigurationAnnotationProcessor,根据是否排序进行分类,然后按照PriorityOrdered,Ordered,nonOrdered以此执行。

对实现了BeanFactoryPostProcessor接口的类按照优先级进行分类
按照排序逐个调用BeanFactoryPostProcessor的实现类

6.registerBeanPostProcessors():获取实现了BeanPostProcessor的bean,并根据是否实现order接口进行排序,并按顺序注册到beanPostProcessors中。

7.initMessageSource():

8.initApplicationEventMulticaster():注册事件广播器

9.onRefresh():获取ServletWebServerFactory(tomcatServletWebServerFactory),创建TomcatWebServer,然后initServletPropertySources

创建TomcatWebServer之后获取需要初始化的servlet,filter

对需要初始化的servlet,filter进行处理

将servlet添加到servletContext中

将filter添加到servletContext中

10.registerListeners():在事件广播器中注册监听器,注册监听器name,如果earlyApplicationEvents存在,则广播事件。

事件广播器中添加监听器

11.finishBeanFactoryInitialization():实例化bean

对还没有实例化的类逐个实例化

先进行实例化之前的操作,再实例化bean。

实例化之前的操作

如果有实现InstantiationAwareBeanPostProcessor, 则执行postProcessBeforeInstantiation

实例化之前的操作

根据实例化策略进行实例化(这里是cglib)包装成BeanWrapper

根据实例化策略(cglib)进行实例化

实例化之后执行后处理

实例化之后的处理

执行postProcessProperties

设置属性之前的处理以及设置属性

属性设置,在AutowiredAnnotationBeanPostProcessor中进行依赖注入

依赖注入

是否实现BeanNameAware,BeanClassLoaderAware,BeanFactoryAware等接口

init之前

执行自定义的init方法之前以及执行自定义的init方法

调用自定义的init方法,在InitDestroyAnnotationBeanPostProcessor中处理

执行自定义的init方法

如果实现了InitializingBean,执行afterPropertiesSet()方法

执行完init之后

然后执行init之后的方法

执行完afterPropertiesSet()之后

12.finishRefresh():主要做的事情是启动tomcat,并发布事件

启动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的过程。

你可能感兴趣的:(Spring容器启动流程)