| 維度 | BeanFactory | ApplicationContext |
|---|---|---|
| 定位 | IOC 核心接口,最小化功能集 | 企業級應用上下文,功能豐富 |
| 核心能力 | getBean、containsBean、isSingleton、getType、getAliases | 繼承 BeanFactory + MessageSource + ResourceLoader + ApplicationEventPublisher + 父子上下文 |
| 初始化時機 | 延遲加載(調用 getBean 時) | 啟動即刷新(預實例化單例) |
| 典型實現 | XmlBeanFactory、DefaultListableBeanFactory | ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、AnnotationConfigApplicationContext |
| 適用場景 | 資源受限、測試、嵌入式 | 生產環境標準選擇 |
DefaultListableBeanFactory 實現了 ConfigurableListableBeanFactory、BeanDefinitionRegistry、Serializable 等接口,是 Bean 註冊表、依賴解析引擎、作用域管理器 的集大成者。
public class XmlBeanFactory extends DefaultListableBeanFactory {
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
}
public XmlBeanFactory(Resource resource, BeanFactory parent) throws BeansException {
super(parent);
this.reader.loadBeanDefinitions(resource); // 關鍵:載入 BeanDefinition
}
}
缺點:不支援國際化、事件發布、資源加載、Web 整合、生命週期回調等企業級特性。
所有 ApplicationContext 實現均繼承 AbstractApplicationContext,核心初始化邏輯在 refresh():
public void refresh() throws BeansException, IllegalStateException {
synchronized (startupShutdownMonitor) {
// 1. 準備上下文環境
prepareRefresh();
// 2. 獲取/創建 BeanFactory(子類實現)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. 配置 BeanFactory 標準化
prepareBeanFactory(beanFactory);
// 4. 子類擴展點:後處理 BeanFactory
postProcessBeanFactory(beanFactory);
// 5. 調用 BeanFactoryPostProcessor(如 PropertyPlaceholderConfigurer)
invokeBeanFactoryPostProcessors(beanFactory);
// 6. 註冊 BeanPostProcessor(如 AutowiredAnnotationBeanPostProcessor)
registerBeanPostProcessors(beanFactory);
// 7. 初始化 MessageSource、事件廣播器等
initMessageSource();
initApplicationEventMulticaster();
// 8. 子類擴展點:初始化特定 Bean(如 DispatcherServlet 初始化 MVC 組件)
onRefresh();
// 9. 註冊監聽器
registerListeners();
// 10. 實例化所有非懶加載單例 Bean(核心階段)
finishBeanFactoryInitialization(beanFactory);
// 11. 發布 ContextRefreshedEvent,完成刷新
finishRefresh();
}
}
DefaultListableBeanFactory,設置序列化 ID、BeanClassLoader、表達式解析器等。loadBeanDefinitions() 中使用 XmlBeanDefinitionReader 解析 XML。configLocations,getConfigResources() 解析為 ClassPathResource[]。getResourceByPath() 返回 FileSystemResource。public interface ResourceLoader {
Resource getResource(String location); // 支援 classpath:、file:、http:、相對路徑
}
ClassPathResource:類路徑資源。FileSystemResource:文件系統絕對/相對路徑。UrlResource:HTTP/FTP/JAR 等 URL。ServletContextResource:Web 應用 /WEB-INF/ 資源。上下文實現 ResourceLoader,委託給內部 DefaultResourceLoader 或子類重寫 getResourceByPath()。
loadBeanDefinitions(Resource) → InputStream → InputSource。doLoadBeanDefinitions():DocumentBuilderFactory 解析 DOM。registerBeanDefinitions(Document):委託 BeanDefinitionDocumentReader(默認 DefaultBeanDefinitionDocumentReader)。public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
Element root = doc.getDocumentElement();
BeanDefinitionParserDelegate delegate = createHelper(readerContext, root);
preProcessXml(root);
parseBeanDefinitions(root, delegate); // 核心遞歸解析
postProcessXml(root);
}
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele.getNamespaceURI())) {
parseDefaultElement(ele, delegate); // 、、
} else {
delegate.parseCustomElement(ele); // 、、 等擴展命名空間
}
}
}
}
解析屬性:id/name、class、scope、lazy-init、autowire、depends-on、init-method/destroy-method、factory-bean/factory-method、constructor-arg、property、lookup-method/replaced-method、meta、qualifier。
生成 BeanDefinitionHolder(包含 BeanName、BeanDefinition、Aliases),調用 BeanDefinitionReaderUtils.registerBeanDefinition() 註冊到 BeanDefinitionRegistry(即 DefaultListableBeanFactory.beanDefinitionMap)。
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected T doGetBean(String name, Class requiredType, Object[] args, boolean typeCheckOnly) {
// 1. 轉換別名、工廠前綴(&)
String beanName = transformedBeanName(name);
// 2. 檢查單例緩存
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null) return getObjectForBeanInstance(sharedInstance, name, beanName, null);
// 3. 原型/其他作用域:創建新實例
if (isPrototypeCurrentlyInCreation(beanName)) throw new BeanCurrentlyInCreationException(beanName);
// 4. 父子上下文委派
BeanFactory parent = getParentBeanFactory();
if (parent != null && !containsBeanDefinition(beanName)) {
return (parent instanceof ApplicationContext)
? ((ApplicationContext) parent).getBean(name)
: parent.getBean(name);
}
// 5. 合併 BeanDefinition(父 Bean 覆蓋)
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 6. 檢查 depends-on
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) for (String dep : dependsOn) getBean(dep);
// 7. 實例化
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> createBean(beanName, mbd, args));
return getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
return getObjectForBeanInstance(createBean(beanName, mbd, args), name, beanName, mbd);
} else {
// 自定義 Scope
Scope scope = scopes.get(mbd.getScope());
return scope.get(beanName, () -> createBean(beanName, mbd, args));
}
}
resolveBeforeInstantiation() → InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()(可返回代理對象,跳過默認實例化)。createBeanInstance() → 構造函數注入 / 工廠方法 / 默認無參構造(通過反射或 CGLIB FastClass)。populateBean() → 解析 property/constructor-arg → 類型轉換 → AutowiredAnnotationBeanPostProcessor 處理 @Autowired/@Value → InstantiationAwareBeanPostProcessor.postProcessProperties()。initializeBean() → Aware 接口回調(BeanNameAware、BeanFactoryAware、ApplicationContextAware 等)。BeanPostProcessor.postProcessBeforeInitialization()。init-method / InitializingBean.afterPropertiesSet() / @PostConstruct。BeanPostProcessor.postProcessAfterInitialization()(AOP 代理在此生成)。DisposableBean/destroy-method/@PreDestroy 到 singletonFactories。| 接口 | 調用時機 | 典型實現 | 作用 |
|---|---|---|---|
| BeanFactoryPostProcessor | BeanDefinition 載入後、Bean 實例化前 | PropertyPlaceholderConfigurer、ConfigurationClassPostProcessor | 修改 BeanDefinition 元數據(佔位符解析、掃描 @Configuration 類) |
| BeanPostProcessor | Bean 實例化前後、初始化前後 | AutowiredAnnotationBeanPostProcessor、AnnotationAwareAspectJAutoProxyCreator | 修改 Bean 實例(依賴注入、AOP 代理、初始化增強) |
ContextRefreshedEvent、ContextClosedEvent、RequestHandledEvent。ApplicationEvent,發布 applicationContext.publishEvent(event),監聽器實現 ApplicationListener<E> 或 @EventListener。@Async @EventListener 或配置 ApplicationEventMulticaster 使用 TaskExecutor。Spring IOC 容器的初始化是一條精心設計的流水線:
ResourceLoader 抽象多種資源來源。BeanDefinitionReader + DocumentReader 將 XML/註解轉為 BeanDefinition。DefaultListableBeanFactory.beanDefinitionMap 持有所有 Bean 元數據。BeanFactoryPostProcessor 修改元數據,BeanPostProcessor 操作實例。掌握這條主線,配合 BeanPostProcessor 擴展點,你就掌握了 Spring 容器的靈魂——在不修改框架代碼的前提下,通過標準化 SPI 接口實現無限擴展。