1.Spring IoC的容器体系
IoC容器是Spring的核⼼模块,是抽象了对象管理、依赖关系管理的框架解决⽅案。Spring 提供了很多 的容器,其中 BeanFactory 是顶层容器(根容器),不能被实例化,它定义了所有 IoC 容器 必须遵从 的⼀套原则,具体的容器实现可以增加额外的功能,⽐如我们常⽤到的ApplicationContext,其下更具 体的实现如 ClassPathXmlApplicationContext 包含了解析 xml 等⼀系列的内容, AnnotationConfigApplicationContext 则是包含了注解解析等⼀系列的内容。Spring IoC 容器继承体系 ⾮常聪明,需要使⽤哪个层次⽤哪个层次即可,不必使⽤功能⼤⽽全的。
BeanFactory顶级接口方法栈如下:
BeanFactory 容器继承体系:
通过其接⼝设计,我们可以看到我们⼀贯使⽤的 ApplicationContext 除了继承BeanFactory的⼦接⼝, 还继承了ResourceLoader、MessageSource等接⼝,因此其提供的功能也就更丰富了。
Spring IoC容器初始化主流程
Spring IoC 容器初始化的关键环节就在 AbstractApplicationContext#refresh() ⽅法中 ,我们查看 refresh ⽅法来俯瞰容器创建的主体流程,主体流程下的具体⼦流程我们后⾯再来讨论。下图是refresh()十大步骤
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 第⼀步:刷新前的预处理
prepareRefresh();
/*
第⼆步:
获取BeanFactory;默认实现是DefaultListableBeanFactory
加载BeanDefition 并注册到 BeanDefitionRegistry
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 第三步:BeanFactory的预准备⼯作(BeanFactory进⾏⼀些设置,⽐如context的类加载器等)
prepareBeanFactory(beanFactory);
try {
// 第四步:BeanFactory准备⼯作完成后进⾏的后置处理⼯作
postProcessBeanFactory(beanFactory);
// 第五步:实例化并调⽤实现了BeanFactoryPostProcessor接⼝的Bean
invokeBeanFactoryPostProcessors(beanFactory);
// 第六步:注册BeanPostProcessor(Bean的后置处理器),在创建bean的前后等执⾏
registerBeanPostProcessors(beanFactory);
// 第七步:初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
initMessageSource();
// 第⼋步:初始化事件派发器
initApplicationEventMulticaster();
// 第九步:⼦类重写这个⽅法,在容器刷新的时候可以⾃定义逻辑
onRefresh();
// 第⼗步:注册应⽤的监听器。就是注册实现了ApplicationListener接⼝的监听器bean
registerListeners();
/*
第⼗⼀步:
初始化所有剩下的⾮懒加载的单例bean
初始化创建⾮懒加载⽅式的单例Bean实例(未设置属性)
填充属性
初始化⽅法调⽤(⽐如调⽤afterPropertiesSet⽅法、init-method⽅法)
调⽤BeanPostProcessor(后置处理器)对实例bean进⾏后置处
*/
finishBeanFactoryInitialization(beanFactory);
/*
第⼗⼆步:
完成context的刷新。主要是调⽤LifecycleProcessor的onRefresh()⽅法,并且发布事
件 (ContextRefreshedEvent)
*/
finishRefresh();
}
......
}
}
Bean对象创建的⼏个关键时机点代码层级的调⽤都在 AbstractApplicationContext 类 的 refresh() ⽅法中,可⻅这个⽅法对于Spring IoC 容器初始化来说相当 关键
分析BeanFactoryPostProcessor 初始化和调⽤情况
分别在构造函数、postProcessBeanFactory ⽅法处打断点,观察调⽤栈,发现
BeanFactoryPostProcessor 初始化在AbstractApplicationContext类refresh⽅法的 invokeBeanFactoryPostProcessors(beanFactory); postProcessBeanFactory 调⽤在AbstractApplicationContext类refresh⽅法的 invokeBeanFactoryPostProcessors(beanFactory);
分析 BeanPostProcessor 初始化和调⽤情况
分别在构造函数、postProcessBeanFactory ⽅法处打断点,观察调⽤栈,发现
BeanPostProcessor 初始化在AbstractApplicationContext类refresh⽅法的 registerBeanPostProcessors(beanFactory);
postProcessBeforeInitialization 调⽤在AbstractApplicationContext类refresh⽅法的 finishBeanFactoryInitialization(beanFactory); postProcessAfterInitialization 调⽤在AbstractApplicationContext类refresh⽅法的 finishBeanFactoryInitialization(beanFactory);
汇总如下:
关键点 | 触发代码 |
---|---|
构造器 | refresh#finishBeanFactoryInitialization(beanFactory)(beanFactory) |
BeanFactoryPostProcessor 初始化 | refresh#invokeBeanFactoryPostProcessors(beanFactory) |
BeanFactoryPostProcessor ⽅法调⽤ | refresh#invokeBeanFactoryPostProcessors(beanFactory) |
BeanPostProcessor 初始化 | registerBeanPostProcessors(beanFactory) |
BeanPostProcessor ⽅法调⽤ | refresh#finishBeanFactoryInitialization(beanFactory) |
BeanFactory创建流程
-
获取BeanFactory⼦流程
-
时序图
AbstractApplicationContext 里面的 refresh() 调用了它里面的 obtainFreshBeanFactory(),进入 obtainFreshBeanFactory() 方法中,调用了AbstractRefreshableApplicationContext 里面的 refreshBeanFactory(),但该方法实际上又调用了 AbstractRefreshableApplicationContext 里面的 createBeanFactory(),接着从 AbstractApplicationContext 调用AbstractRefreshableApplicationContext 中的 getBeanFactory() 方法,并将 DefaultListableBeanFactory 返回 (默认实现的是DefaultListableBeanFactory)
-
-
BeanDefinition加载解析及注册⼦流程
-
该⼦流程涉及到如下⼏个关键步骤
-
Resource定位:指对BeanDefinition的资源定位过程。通俗讲就是找到定义Javabean信息的XML⽂ 件,并将其封装成Resource对象。
-
BeanDefinition载⼊ :把⽤户定义好的Javabean表示为IoC容器内部的数据结构,这个容器内部的数据结构就是BeanDefinition。
注册BeanDefinition到 IoC 容器
-
-
过程分析
-
⼦流程⼊⼝在 AbstractRefreshableApplicationContext#refreshBeanFactory ⽅法中
-
依次调⽤多个类的 loadBeanDefinitions ⽅法 —> AbstractXmlApplicationContext —> AbstractBeanDefinitionReader —> XmlBeanDefinitionReader ⼀直执⾏到 XmlBeanDefinitionReader 的 doLoadBeanDefinitions ⽅法
-
我们重点观察XmlBeanDefinitionReader 类的 registerBeanDefinitions ⽅法,期间产⽣了多 次重载调⽤,我们定位到最后⼀个
此处我们关注两个地⽅:⼀个createRederContext⽅法,⼀个是 DefaultBeanDefinitionDocumentReader类的registerBeanDefinitions⽅法,先进⼊ createRederContext ⽅法看看
我们可以看到,此处 Spring ⾸先完成了 NamespaceHandlerResolver 的初始化。 我们再进⼊ registerBeanDefinitions ⽅法中追踪,调⽤了 DefaultBeanDefinitionDocumentReader#registerBeanDefinitions ⽅法
进⼊ doRegisterBeanDefinitions ⽅法
进⼊ parseBeanDefinitions ⽅法
进⼊ parseDefaultElement ⽅法
进⼊ processBeanDefinition ⽅法
⾄此,注册流程结束,我们发现,所谓的注册就是把封装的 XML 中定义的 Bean信息封装为 BeanDefinition 对象之后放⼊⼀个Map中,BeanFactory 是以 Map 的结构组织这些 BeanDefinition 的。
可以在DefaultListableBeanFactory中看到此Map的定义
/** Map of bean definition objects, keyed by bean name. */ private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
-
时序图
-
-