首先,初始化容器最核心方法是AbstractApplicationContext类的refresh()方法,如下
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//初始化前的准备工作
prepareRefresh();
// 让子类刷新bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// bean工厂的使用前的准备工作
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
..............
}
}
现简要介绍容器初始化大的流程:
-
首先
ResourceLoader从存储介质中加载Spring配置信息,并把配置信息用Rescource表示; -
BeanDefinitionReader读取Resource,把配置文件解析成一个BeanDefinition对象,并保存到BeanDefinitionRegistry中; -
容器扫描
BeanDefinitionRegistry中的BeanDefinition,使用Java的反射机制识别bean工厂后处理器(BeanFactoryPostProcessor接口)的Bean,然后调用这些bean工厂后处理器对BeanDefinitionRegistry中的BeanDefinition进行加工处理1)对使用到占位符的元素标签进行解析,得到最终的配置值,这意味对一些半成品式的BeanDefinition对象进行加工处理并得到成品的BeanDefinition对象;
2)对BeanDefinitionRegistry中的BeanDefinition进行扫描,通过Java反射机制找出所有属性编辑器的Bean(实现java.beans.PropertyEditor接口的Bean),并自动将它们注册到Spring容器的属性编辑器注册表中(PropertyEditorRegistry);
4.Spring容器从BeanDefinitionRegistry中取出加工后的BeanDefinition,并调用InstantiationStrategy着手进行Bean实例化的工作;
5.在实例化Bean时,Spring容器使用BeanWrapper对Bean进行封装,BeanWrapper提供了很多以Java反射机制操作Bean的方法,它将结合该Bean的BeanDefinition以及容器中属性编辑器,完成Bean属性的设置工作;
6.利用容器中注册的Bean后处理器(实现BeanPostProcessor接口的Bean)对已经完成属性设置工作的Bean进行后续加工,直接装配出一个准备就绪的Bean。