ApplicationContext 繼承 BeanFactory,擴充了事件發布、國際化、資源載入、掃描註冊等企業級功能。其核心邏輯集中在 refresh() 方法,該方法同步執行,確保容器啟動過程的原子性。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh(); // 1. 準備:啟動時間、活躍標記、屬性源初始化
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 2. 獲取/建立 BeanFactory
prepareBeanFactory(beanFactory); // 3. 配置 BeanFactory 標準特性
try {
postProcessBeanFactory(beanFactory); // 4. 子類後處理 BeanFactory
invokeBeanFactoryPostProcessors(beanFactory); // 5. 執行 BeanFactoryPostProcessor(如 PropertyPlaceholderConfigurer)
registerBeanPostProcessors(beanFactory); // 6. 註冊 BeanPostProcessor(AOP、自動代理等)
initMessageSource(); // 7. 國際化 MessageSource
initApplicationEventMulticaster(); // 8. 事件廣播器
onRefresh(); // 9. 子類擴充點(Web 容器啟動 Servlet 等)
registerListeners(); // 10. 註冊 ApplicationListener
finishBeanFactoryInitialization(beanFactory); // 11. 實例化所有非懶加載單例
finishRefresh(); // 12. 發布 ContextRefreshedEvent
} catch (BeansException ex) {
destroyBeans(); cancelRefresh(ex); throw ex;
} finally {
resetCommonCaches();
}
}
}
startupDate、active=true、closed=false。initPropertySources():預留擴充點,子類可注入額外屬性源(如從配置中心拉取)。validateRequiredProperties():檢查必要屬性是否可解析。earlyApplicationEvents 集合,收集廣播器就緒前的早期事件。ClassLoader、BeanExpressionResolver(支援 SpEL #{...})、PropertyEditorRegistrar(類型轉換,如 String→Date)。ApplicationContextAwareProcessor,自動注入 ApplicationContext 等 Aware 介面。ResourceLoaderAware、ApplicationEventPublisherAware 等。BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext 本身。LoadTimeWeaver(AspectJ LTW 支援)。environment、systemProperties、systemEnvironment。Spring Expression Language(獨立模組,僅依賴 core),支援運行時構建複雜表達式、存取物件圖屬性、呼叫方法。常見於 @Value("#{systemProperties['os.name']}") 或 XML <property value="#{bean.method()}" />。
Spring 內建類型轉換器,若需自定義(如 String→Date 格式),可透過 CustomEditorConfigurer 註冊:
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date">
<bean class="com.xxx.MyDateEditor">
<property name="format" value="yyyy-MM-dd HH:mm:ss"/>
</bean>
</entry>
</map>
</property>
</bean>
或實作 PropertyEditorRegistrar 統一註冊多個編輯器。
典型應用:PropertyPlaceholderConfigurer 解析 ${...} 佔位符,合併屬性檔、轉換屬性、處理屬性值,供後續 Bean 實例化使用。
initMessageSource():載入 messageSource Bean(固定 ID),支援 ResourceBundleMessageSource 讀取 message_en.properties、message_zh_CN.properties。initApplicationEventMulticaster():建立 SimpleApplicationEventMulticaster,支援同步/非同步廣播。registerListeners():掃描 ApplicationListener Bean 並註冊,同時發布早期收集的事件。一般不直接實作 ApplicationContext(介面過多),建議繼承 ClassPathXmlApplicationContext 並覆寫 initPropertySources()、onRefresh() 等保護方法,實現自定義啟動邏輯。