上篇文章讲述了bean的创建,是本篇文章的基础,想了解此文章最好了解下bean的创建过程。
spring容器的扩展是对spring容器功能的完善也是使用spring的入口,下面会针对ClassPathXmlApplicationContext(spring配置文件的入口)顶级类及父类讲解:
上图可以清晰的看到各个类的继承关系,我们根据步骤讲解下各个类的作用
ClassPathXmlApplicationContext(step1
):功能上初始化容器及各种注册处理器,继承关系上加载配置文件及刷新上下文
AbstractXmlApplicationContext(step2
):主要实现loadBeanDefinitions
对配置文件里的bean的加载
AbstractRefreshableConfigApplicationContext(step3
):setConfigLocations
设置文件配置信息
AbstractRefreshableApplicationContext(step4
):初始化容器DefaultListableBeanFactory
并提供BeanFactory实例
AbstractApplicationContext(step5
):完成上下文Context初始化流程,核心代码如下:
// 此方法的主要目的是创建一个具备完善功能的DefaultListableBeanFactory
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 为Context设置上下文激活,关闭标志
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 获取BeanFactory实例(spring容器已经初始化)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// ...
//prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 留给子类实现
//postProcessBeanFactory(beanFactory);
// 功能扩展:对实现BeanFactoryPostProcessor接口的类的执行
// 该方法主要目的是将spring所需的组件注册到容器中,例如:带有@Component注解组件类的解析
// 不过支持注解解析的applicationContext是AnnotationConfigApplicationContext而非上文提到的ClassPathXmlApplicationContext
invokeBeanFactoryPostProcessors(beanFactory);
// 注册BeanPostProcessor,此BeanPostProcessor是spring在创建bean过程中的扩展功能点,类似于拦截器,对于未创建bean功能的完善,例如@Autowire自动装配的实现、aop功能的实现
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
//initMessageSource();
// Initialize event multicaster for this context.
//initApplicationEventMulticaster();
// 留给子类实现
// 其中在子类ServletWebServerApplicationContext中此方法主要用于初始化tomcat实例
onRefresh();
// Check for listener beans and register them.
//registerListeners();
// 提前实例化注册的bean
finishBeanFactoryInitialization(beanFactory);
// 其中在子类ServletWebServerApplicationContext中此方法主要用于tomcat启动
finishRefresh();
}
catch (BeansException ex) {
// if (logger.isWarnEnabled()) {
// logger.warn("Exception encountered during context initialization - " +
// "cancelling refresh attempt: " + ex);
// }
// Destroy already created singletons to avoid dangling resources.
// destroyBeans();
// Reset 'active' flag.
// cancelRefresh(ex);
// Propagate exception to caller.
// throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
// resetCommonCaches();
}
}
}
注:被注掉语句不是本文讲解的重点