Spring 容器啟動是一條精密的流水線。本文以 ClassPathXmlApplicationContext 為切入點,追蹤 refresh() 核心模板方法,深入 obtainFreshBeanFactory() → refreshBeanFactory() → loadBeanDefinitions(),揭示 BeanDefinition 裝載的完整調用鏈與關鍵決策點。
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) {
super(parent);
setConfigLocations(configLocations); // 設置配置文件位置
if (refresh) refresh(); // 核心啟動開關
}
定義於 AbstractApplicationContext,採用模板方法模式,完整步驟:
prepareRefresh():記錄啟動時間、標記激活狀態、驗證必需屬性obtainFreshBeanFactory():創建 BeanFactory 並完成 BeanDefinition 裝載 (核心)prepareBeanFactory(beanFactory):配置工廠上下文 (類加載器、SpEL 解析器、後置處理器等)postProcessBeanFactory(beanFactory):子類擴展點,修改 BeanFactory 內部狀態invokeBeanFactoryPostProcessors(beanFactory):調用 BeanFactoryPostProcessor (如 PropertyPlaceholderConfigurer 解析 ${...})registerBeanPostProcessors(beanFactory):註冊 BeanPostProcessor (攔截 Bean 初始化前後)initMessageSource():初始化國際化消息源initApplicationEventMulticaster():初始化事件廣播器onRefresh():模板方法,Web 環境初始化 Servlet 容器等registerListeners():註冊監聽器finishBeanFactoryInitialization(beanFactory):實例化所有非懶加載單例 BeanfinishRefresh():發布 ContextRefreshedEvent,清理緩存protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory(); // 核心:創建並裝載 BeanDefinition
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
return beanFactory;
}
定義於 AbstractRefreshableApplicationContext,final 禁止覆蓋:
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans(); // 銷毀現有單例
closeBeanFactory(); // 關閉舊工廠
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory(); // 創建核心工廠
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory); // 設置允許覆蓋、循環引用等策略
loadBeanDefinitions(beanFactory); // 【核心入口】裝載 BeanDefinition
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source", ex);
}
}
ConfigurableListableBeanFactory,支撐完整 Bean 生命周期管理allowBeanDefinitionOverriding (默認 true)、allowCircularReferences (默認 true)AbstractXmlApplicationContext 解析 XML、AnnotatedBeanDefinitionReader 掃描註解)loadBeanDefinitions(beanFactory) 在 AbstractXmlApplicationContext 中具體實現,將調用 XmlBeanDefinitionReader 解析 XML 文件,生成 BeanDefinition 對象並註冊到 DefaultListableBeanFactory 的 beanDefinitionMap 中。下一篇將深入剖析 XML 解析流程、命名空間處理、<bean> 元素到 BeanDefinition 的轉換邏輯。
refresh() 是容器啟動總模板,第 2 步完成 BeanDefinition 裝載obtainFreshBeanFactory() → refreshBeanFactory() → loadBeanDefinitions() 為核心調用鏈DefaultListableBeanFactory 是 BeanDefinition 的最終註冊倉庫loadBeanDefinitions() 為模板方法,具體解析策略由子類決定 (XML、註解、Groovy 等)理解這條主幹鏈路,是掌握 Spring IOC 容器啟動機制、排查啟動失敗、擴展配置解析的關鍵地圖。