以經典 XML 配置為例,啟動流程僅四行代碼,卻涵蓋 Spring IOC 核心生命週期:
Resource resource = new ClassPathResource("spring-core.xml");
XmlBeanFactory beanFactory = new XmlBeanFactory(resource);
MyBean myBean = (MyBean) beanFactory.getBean("myBean");
myBean.sayHello();
本文將從Bean 解析註冊與Bean 獲取實例化兩大階段,梳理核心源碼邏輯。
public XmlBeanFactory(Resource resource) throws BeansException {
this(resource, null);
}
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory); // 初始化 DefaultListableBeanFactory
this.reader.loadBeanDefinitions(resource); // 觸發解析
}
XmlBeanFactory 繼承 DefaultListableBeanFactory(核心 IOC 容器實現),內持有 XmlBeanDefinitionReader 負責 XML 解析。
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
// 1. 防循環引用檢查
// 2. 獲取 InputStream → 構造 InputSource
// 3. 調用 doLoadBeanDefinitions(inputSource, resource)
}
VALIDATION_AUTO、VALIDATION_XSD、VALIDATION_DTDorg.w3c.dom.Documentpublic int registerBeanDefinitions(Document doc, Resource resource) {
BeanDefinitionDocumentReader reader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
reader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
實際工作由 DefaultBeanDefinitionDocumentReader 完成:
protected void doRegisterBeanDefinitions(Element root) {
// 1. 處理 profile 屬性(環境隔離)
// 2. preProcessXml(root) - 模板方法預留擴展
// 3. parseBeanDefinitions(root, delegate) - 核心解析
// 4. postProcessXml(root) - 模板方法預留擴展
}
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
// 默認命名空間:, , 等
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)) {
parseDefaultElement(ele, delegate); // 解析 等
} else {
delegate.parseCustomElement(ele); // 解析自定義標籤
}
}
}
} else {
delegate.parseCustomElement(root); // 非默認命名空間直接委派
}
}
至此,XML 靜態配置轉化為內存中的 BeanDefinition 元數據,註冊至 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. 轉換 beanName(處理 alias、FactoryBean 前綴 &)
final String beanName = transformedBeanName(name);
// 2. 檢查單例緩存(含早期暴露的 ObjectFactory,解決循環依賴)
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == 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.getBean(nameToLookup, args);
}
// 5. 合併 BeanDefinition(處理父子定義繼承)
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 6. 處理 depends-on 依賴
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) throw new BeanCreationException(...);
registerDependentBean(dep, beanName);
getBean(dep); // 遞歸初始化依賴
}
}
// 7. 根據 scope 創建實例
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> createBean(beanName, mbd, args));
return getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
Object prototypeInstance = createBean(beanName, mbd, args);
return getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
Scope scope = scopes.get(mbd.getScope());
Object scopedInstance = scope.get(beanName, () -> createBean(beanName, mbd, args));
return getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
}
getSingleton(beanName, ObjectFactory) 中,實例創建前先將 ObjectFactory 放入 singletonFactories 三級緩存singletonObjects:完成初始化的單例earlySingletonObjects:早期暴露的單例(已實例化,未完成屬性注入)singletonFactories:ObjectFactory 延遲創建getObjectForBeanInstance 判斷實例是否為 FactoryBean,若是則調用 getObject() 獲取真實物件,&beanName 可獲取 FactoryBean 本身。
若 requiredType 不匹配,嘗試 TypeConverter.convertIfNecessary 轉換。
DefaultListableBeanFactory
├── BeanDefinitionRegistry (註冊 BeanDefinition)
├── BeanFactory (getBean 入口)
├── AliasRegistry (別名管理)
├── SingletonBeanRegistry (單例管理)
└── ConfigurableBeanFactory (配置能力)
ClassPathResource 封裝定位資源XmlBeanDefinitionReader → Document → BeanDefinitionDocumentReaderBeanDefinition 存入 beanDefinitionMapgetBean → doGetBeandepends-on、構造器/Setter 注入遞歸createBean → 實例化 → 屬性填充 → 初始化(Aware、InitializingBean、@PostConstruct)BeanPostProcessor 前後置增強(AOP 代理在此生成)DestructionAwareBeanPostProcessorgetObjectForBeanInstance 處理 FactoryBean、類型轉換理解此流程,是掌握 Spring 核心、排查啟動異常、實現擴展點的基石。