spring refresh 方法
斜月 人气:01 前言
在项目开发和面试过程中 spring
都是非常重要的,在前文中已经讲述了Spring BeanFactory 与 FactoryBean 的区别,在后续的文章中将继续更新 Spring
源码心得。了解原理性的一些内容之后就会在应用能够得心应手,在项目开发和面试中,就能很好地 battle 和 show muscle。
2 源码入口哪里找
Spring 的源码阅读,需要找到入口文件,一般情况下在 Spring 项目中,由 tomcat 容器启动后加载项目中设置的 web.xml,在改文件中添加项目的配置文件,监听器等内容,其中 DispatcherServlet 尤为重要,其 onRefresh
方法就是其核心操作。不过随着 springboot 的诞生,配置化的思想成型后,获取源码的入口就相对简单了,核心需要关注 AbstractApplicationContext.refresh
。
获取方法的入口常见的如下所示:
# 通过配置文件来读取 ClassPathXmlApplicationContext ct = new ClassPathXmlApplicationContext("bean.xml"); # 通过配置类来加载 AnnotationConfigApplicationContext ct = new AnnotationConfigApplicationContext(MainConfig.class); # 两者都是AbstractApplicationContext 的子类 AbstractApplicationContext
如下图所示,通过配置文件来加载的 ClassPathXmlApplicationContext 是在构造方法中调用了其父类的 refresh 方法,这个方法就是核心,就是大家都知道的 AbstractApplicationContext.refresh()
。
3 refresh 核心方法
关于源码的阅读,因其复杂的文件结构,在梳理其结构时,需要抓大放小,不宜深入细节,否则就容易迷路,不记得来时的路了。下图便是核心方法 AbstractApplicationContext.refresh
对于 refresh 方法主要分为以下核心的 12 个方法:
- 1
prepareRefresh()
刷新前的预处理,调用 initPropertySources() 方法初始化一些属性设置,调用 getEnvironment().validateRequiredProperties() 校验属性的合法性,设置 earlyApplicationEvents= new LinkedHashSet() 保存容器中较早期的事件。 - 2
obtainFreshBeanFactory()
获取 BeanFactory,创建一个刷新的 Bean 工厂,refreshBeanFactory() 并设置容器 ID,然后将创建的 DefaultListableBeanFactory 的对象进行返回。 - 3
prepareBeanFactory(beanFactory)
BeanFactory 的预准备工作,设置 BeanFactory 的类加载器和表达式解析器,并添加 BeanPostProcessor【ApplicationContextAwareProcessor】,设置自动装配的接口,添加 BeanPostProcessor。 - 4
postProcessBeanFactory(beanFactory)
BeanFactory 准备工作完成后进行的后置处理工作,子类通过重写这个方法来做进一步的设置。 - 5
invokeBeanFactoryPostProcessors(beanFactory)
执行BeanFactoryPostProcessor 和 BeanFactory
方法的后置处理器。在BeanFactory
标准初始化之后执行BeanFactoryPostProcessor
和BeanDefinitionRegistryPostProcessor
。先执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry
方法,按照PriorityOrdered 、Ordered 和其它未设置优先级
来执行,然后按照同样的优先级来执行BeanFactoryPostProcessor.postProcessBeanFactory
方法。 - 6
registerBeanPostProcessors(beanFactory)
注册 BeanPostProcessor(Bean 的后置处理器),不同接口类型的BeanPostProcessor
在 Bean 创建前后的执行时机是不一样的。 - 7
initMessageSource()
初始化MessageSource
组件, 做国际化功能、消息绑定、消息解析等。 - 8
initApplicationEventMulticaster()
初始化事件派发器,如果容器中没有事件派发器,那么就创建一个SimpleApplicationEventMulticaster
并添加到容器中。 - 9
onRefresh()
留给子容器(子类),例如在 springboot 中,用来创建 tomcat、jetty 容器并启动。 - 10
registerListeners()
给容器中将所有项目里面的ApplicationListener
注册进来,并将监听器注册到事件派发器中。 - 11
finishBeanFactoryInitialization(beanFactory)
初始化所有剩下的单实例 bean,这个方法是核心方法,在后续的主要流程中会详细讲解。 - 12
finishRefresh()
完成BeanFactory
的初始化创建工作,IOC 容器就创建完成。
4 总结
在本文中,讲述了 Spring
容器启动的核心方法 refresh
, 介绍了主要的启动流程方法
加载全部内容