【Spring 源码】ApplicationContext 容器的加载原理(一)
文章目录
一、容器初始化位置
容器的初始化会包含许多操作,主要集中在 refresh()
方法中,其中等待容器初始化完毕以后,还会有其他功能的扩展,比如 AspectJ 或者 事件监听器等。
以及在容器初始化完成以后,会对非延迟初始化的 Bean 进行预实例化,等待用户通过 getBean()
方法获取并且注入数据。
1. ClassPathXmlApplicationContext 构造函数
// 新建 ApplicationContext 对象
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("MyBean.xml");
// ApplicationContext 初始化详情
public ClassPathXmlApplicationContext(
String[] configLocations,
boolean refresh,
@Nullable ApplicationContext parent
) throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
2. 初始化流程
refresh()
中有许多方法,第一眼看上去不知道 Spring 具体在初始化什么,细细理清的话其实方法中一共有四大步:
- 对容器做初始化,并且从注册文件中读取 Bean 并提前实例化 Bean
- 注册并调用 BeanPostProcessors 和 BeanFactoryPostProcessors
- 初始化企业级功能
- 完成初始化
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备环境
prepareRefresh();
// 初始化容器并且获取 xml 文件中定义的 Bean
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 容器功能扩展
prepareBeanFactory(beanFactory);
try {
// 注册 ServletContextAwareProcessor
postProcessBeanFactory(beanFactory);
// 调用 BeanFactoryPostProcessors
invokeBeanFactoryPostProcessors(beanFactory);
// 注册 BeanFactoryPostProcessors
registerBeanPostProcessors(beanFactory);
// 初始化消息资源
initMessageSource();
// 初始化事件传播
initApplicationEventMulticaster();
// 用户可以重写此方法进行初始化过程中的方法调用
onRefresh();
// 注册监听器
registerListeners();
// 提前实例化非延迟初始化的 Bean
finishBeanFactoryInitialization(beanFactory);
// 完成初始化容器
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger