IOC (Inversion of Control):將對象創建、依賴管理權從應用代碼「反轉」給容器。
DI (Dependency Injection):容器在創建 Bean 時,自動將依賴注入到目標對象(構造器/Setter/字段)。
┌─────────────────────────────────────────────────────────────────────────────┐
│ Spring IOC 容器啟動階段 │
├─────────────────────────────────────────────────────────────────────────────┤
│ 1. Resource Loading → 加載配置元數據 (XML/Annotation/JavaConfig) │
│ 2. BeanDefinition Parsing → 解析為 BeanDefinition (內部元數據模型) │
│ 3. BeanDefinition Registry → 註冊到 BeanDefinitionRegistry (Map 結構) │
│ 4. BeanFactoryPostProcessor→ 後處理器修改 BeanDefinition (如 PropertyPlaceholderConfigurer) │
└─────────────────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────────────────┐
│ Bean 實例化階段 │
├─────────────────────────────────────────────────────────────────────────────┤
│ 1. Instantiation → 反射/CGLIB 創建 Bean 實例 │
│ 2. Property Population → 依賴注入 (Setter/構造器/字段) │
│ 3. BeanPostProcessor → 前/後置處理 (如 @Autowired, AOP 代理創建) │
│ 4. Initialization → @PostConstruct, InitializingBean, init-method│
│ 5. Ready for Use → 放入單例池 (singletonObjects) │
└─────────────────────────────────────────────────────────────────────────────┘
| 組件 | 核心接口/類 | 職責 |
|---|---|---|
| 資源加載 | Resource, ResourceLoader |
統一抽象配置文件來源 (classpath、文件系統、URL) |
| 解析引擎 | BeanDefinitionReader (XmlBeanDefinitionReader 等) |
將 XML/註解轉為 BeanDefinition |
| 註冊表 | BeanDefinitionRegistry (DefaultListableBeanFactory) |
存儲 beanName → BeanDefinition 映射 |
| 後處理器 | BeanFactoryPostProcessor, BeanPostProcessor |
擴展點:修改定義 / 包裝實例 (AOP、@Autowired 實現) |
| 實例化策略 | InstantiationStrategy (CglibSubclassing / Simple) |
反射或字節碼生成創建實例 |
| 屬性填充 | BeanWrapper, PropertyValues |
統一屬性訪問,支援類型轉換、嵌套路徑 |
// 1. BeanDefinition 元數據模型
public class BeanDefinition {
private String beanClassName;
private boolean singleton = true;
private boolean lazyInit = false;
private PropertyValues propertyValues; // 依賴屬性
// getter/setter 省略
}
// 2. 簡易 BeanFactory
public class SimpleBeanFactory implements BeanFactory {
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
public void registerBeanDefinition(String name, BeanDefinition bd) {
beanDefinitionMap.put(name, bd);
}
@Override
public Object getBean(String name) {
// 單例檢查
Object singleton = singletonObjects.get(name);
if (singleton != null) return singleton;
BeanDefinition bd = beanDefinitionMap.get(name);
if (bd == null) throw new NoSuchBeanDefinitionException(name);
// 實例化
Object bean = createBean(bd);
// 依賴注入
populateBean(bean, bd.getPropertyValues());
// 初始化回調
initializeBean(bean, name);
// 註冊單例
if (bd.isSingleton()) singletonObjects.put(name, bean);
return bean;
}
private Object createBean(BeanDefinition bd) {
try {
Class<?> clazz = Class.forName(bd.getBeanClassName());
return clazz.getDeclaredConstructor().newInstance();
} catch (Exception e) { throw new BeanCreationException(e); }
}
private void populateBean(Object bean, PropertyValues pvs) {
// 簡化:遍歷 PropertyValues 反射設置屬性
for (PropertyValue pv : pvs.getPropertyValues()) {
try {
Field field = bean.getClass().getDeclaredField(pv.getName());
field.setAccessible(true);
field.set(bean, pv.getValue());
} catch (Exception e) { throw new BeanCreationException(e); }
}
}
private void initializeBean(Object bean, String name) {
// 支援 InitializingBean / @PostConstruct / init-method
if (bean instanceof InitializingBean) {
((InitializingBean) bean).afterPropertiesSet();
}
// ... 其他初始化邏輯
}
}
// 典型應用:PropertyPlaceholderConfigurer 解析 ${xxx}
public class PropertyPlaceholderConfigurer implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) {
// 遍歷所有 BeanDefinition,替換屬性值中的 ${key} 為 properties 文件值
}
}
// 核心應用:AutowiredAnnotationBeanPostProcessor、AOP 代理創建
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String name) {
// 初始化前:如處理 @Autowired 注入
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String name) {
// 初始化後:如創建 AOP 代理
if (needProxy(bean)) return Proxy.newProxyInstance(...);
return bean;
}
}
// 用戶實現 FactoryBean,getObject() 返回真實對象
public class DataSourceFactoryBean implements FactoryBean<DataSource> {
private String url, username, password;
@Override
public DataSource getObject() {
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl(url); ds.setUsername(username); ds.setPassword(password);
return ds;
}
@Override public Class<?> getObjectType() { return DataSource.class; }
@Override public boolean isSingleton() { return true; }
}
┌────────────────────────────────────────────────────────────┐ │ DefaultSingletonBeanRegistry 三級緩存 │ ├────────────────────────────────────────────────────────────┤ │ singletonObjects → 完全初始化好的單例 Bean │ │ earlySingletonObjects → 早期暴露的單例 Bean (實例化後、屬性填充前) │ │ singletonFactories → ObjectFactory (創建早期引用的工廠) │ └────────────────────────────────────────────────────────────┘ 流程: A 依賴 B,B 依賴 A 1. A 實例化 → 放入 singletonFactories (ObjectFactory) 2. A 屬性填充需 B → getBean(B) 3. B 實例化 → 放入 singletonFactories 4. B 屬性填充需 A → getBean(A) → 從 singletonFactories 獲取 ObjectFactory → getObject() 返回早期 A 引用 → 放入 earlySingletonObjects 5. B 完成初始化 → 移至 singletonObjects 6. A 繼續填充屬性 (已獲取 B) → 完成初始化 → 移至 singletonObjects
僅支援 Setter/字段注入 的循環依賴。構造器注入循環依賴無法解決(需打破循環或使用 @Lazy)。
Spring IOC 容器以 BeanDefinition 為核心元數據模型,通過 資源加載 → 解析註冊 → 後處理增強 → 實例化 → 依賴注入 → 初始化 → 緩存 的標準化流程,構建了極具擴展性的對象管理體系。理解其源碼級實現,不僅能排查疑難雜症(循環依賴、Bean 不生效、AOP 失效),更能在框架設計、中間件開發中復用其精妙的擴展點機制。