容器初始化及SpringBean加载过程
对于Spring项目,应用上下文又常叫做Spring容器。
1. 创建Spring容器
Spring容器类型:AnnotationConfigServletWebServerApplicationContext。
容器中会生成一个DefaultListableBeanFactory类型的对象(下文简称beanFactory)。
DefaultListableBeanFactory继承了DefaultSingletonBeanRegistry。DefaultSingletonBeanRegistry就是Spring Bean管理的关键。
DefaultSingletonBeanRegistry继承了SimpleAliasRegistry并实现SingletonBeanRegistry,使得它既有别名注册的功能,又有单例bean注册的功能。它是一个通用的存储共享bean实例的地方。
- AliasRegistry:提供别名注册的接口。
- SimpleAliasRegistry:它简单地实现了AliasRegistry接口。
- SingletonBeanRegistry:提供单例bean注册的接口。
创建Spring容器这个过程目前还未创建任何Spring管理的Bean实例。
2. 获取异常报告器
注册的SpringBean:
-
autoConfigurationReport -> ConditionEvaluationReport(条件评估报告)。
记录自动化配置过程中条件匹配的详细信息及日志信息。
3. 准备Spring容器
注册的SpringBean:
- springApplicationArguments -> DefaultApplicationArguments
- org.springframework.boot.context.ContextIdApplicationContextInitializer$ContextId -> ContextIdApplicationContextInitializer$ContextId
- springBootLoggingSystem -> LogbackLoggingSystem
- springBootBanner -> SpringApplicationBannerPrinter$PrintedBanner
- springBootLogFile -> LogFile
- springBootLoggerGroups -> LoggerGroups
4. 刷新Spring容器
-
准备刷新
prepareRefresh()
刷新上下文环境,初始化上下文环境,对系统的环境便利或者系统属性进行准备和校验
-
beanFactory刷新
obtainFreshBeanFactory()
销毁原有beanFactory,获取新的beanFactory,为每个bean生成BeanDefinition等。
-
准备bean工厂
prepareBeanFactory(beanFactory)
对bean工厂的工作功能进行填充,如:@Autowired、设置spel表、设置编辑注册器、添加applicationContextAwaerprocessor处理器等
注册的SpringBean:
- systemEnvironment -> Collections$UnmodifiableMap
- environment -> StandardServletEnvironment
- systemProperties -> Properties
-
后置处理bean工厂
postProcessBeanFactory(beanFactory)
允许在上下文子类中对 bean 工厂进行后置处理。
在beanfactory加载完成所有的bean后,想修改其中某个bean的定义,或者对beanFactory做一些其他的配置,就可以在子类中对beanFactory进行后置处理(子类通过实现接口BeanFactoryPostProcessor来自定义后置处理)。
BeanFactoryPostProcessor是针对BeanFactory的扩展,主要用在bean实例化之前,读取bean的定义,并可以修改它。
后置处理器执行的时间是:在所有的beanDenifition加载完成之后,bean实例化之前执行。
-
调用bean工厂后置处理器
invokeBeanFactoryPostProcessors(beanFactory)
调用所有注册的、原始的bean工厂后置处理器。会实例化和调用所有 BeanFactoryPostProcessor(包括其子类 BeanDefinitionRegistryPostProcessor)。
- 先处理用户手动注册的BeanFactoryPostProcessor,分为BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor,并且BeanDefinitionRegistryPostProcessor会先调用其postXX方法
- 从容器获取所有的BeanDefinitionRegistryPostProcessor类型,先处理实现PriorityOrdered类型的
- 再从容器获取所有的BeanDefinitionRegistryPostProcessor类型,处理实现Ordered类型的
- 再从容器获取所有的BeanDefinitionRegistryPostProcessor类型,处理剩下的,这里有个递归,知道所有的BeanDefinitionRegistryPostProcessor都处理完
- BeanDefinitionRegistryPostProcessor也是BeanFactoryPostProcessor,最后处理BeanDefinitionRegistryPostProcessor从BeanFactoryPostProcessor继承的方法
- 最后处理一般的BeanFactoryPostProcessor的postXXX方法。
需要注意:-
BeanDefinitionRegistryPostProcessor有可能会动态新增新的BeanDefinitionRegistryPostProcessor,所有这里每次都从容器中重新获得所有的BeanDefinitionRegistryPostProcessor。
-
BeanDefinitionRegistryPostProcessor的回调方法,先于BeanFactoryPostProcessor的回调方法执行。
注册的SpringBean:
- 所有的bean工厂后置处理器。
这一步完成后,容器中已有完整的BeanDefinition集合(所有需要spring容器管理的bean的BeanDefinition都在这里)。
-
注册bean后置处理器
registerBeanPostProcessors(beanFactory)
实例化和注册beanFactory中扩展了BeanPostProcessor的bean。例如:
- AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)
- RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)
- CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。
BeanPostProcessor是针对bean的扩展,主要用在bean实例化之后,执行初始化方法前后,允许开发者对 bean 实例进行修改。注册的SpringBean:
- 所有的bean后置处理器。
这一步完成后,后续的生成的Spring bean已经支持自动装配(@Autowired、@Resource)等。
-
初始化消息源
initMessageSource()
初始化国际化工具类MessageSource。
注册的SpringBean:
- 消息源MessageSource。
-
初始化应用事件广播器
initApplicationEventMulticaster()
初始化应用事件广播器。
注册的SpringBean:
- 应用事件广播器ApplicationEventMulticaster。
- 应用事件广播器ApplicationEventMulticaster。
-
初始化特殊的bean
onRefresh()
启动内置Web容器(如Tomcat),并初始化一些特殊的bean(如DataSource)。
这阶段主要完成的事情:
- 初始化主题功能
- 启动SpringBoot的嵌入式Tomcat服务器
- 启动web容器
- 创建ServletContext
- 创建Listener
- 创建Filter
- 创建Servlet
- 初始化一些特殊的bean
注册的SpringBean:
- web容器相关(如:ServletContext、Listener、Filter、Servlet等)
- 一些特殊的bean(如DataSource)
-
注册监听器
registerListeners()
注册监听器,并且广播earlyApplicationEvents(早期应用事件)。
-
完成bean工厂初始化
finishBeanFactoryInitialization(beanFactory)
该方法会初始化所有剩余的非懒加载单例bean,并调用BeanPostProcessors。
除了一些内部的 bean、实现了BeanFactoryPostProcessor 接口的 bean、实现了BeanPostProcessor 接口的 bean,其他的非懒加载单例bean都会在这个方法中被初始化,BeanPostProcessor的触发也是在这个方法中。
-
完成刷新
finishRefresh()
通知生命周期处理器LifecycleProcessor完成刷新过程,同时发出ContextRefreshEvent通知容器刷新完成。
该阶段完成的事情:
- 清除上下文资源缓存(如扫描中的ASM元数据)
- 初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)
- 发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作
至此,容器初始化及SpringBean创建完成。