IoC (Inversion of Control,控制反轉) 是 Spring 框架的核心設計哲學,將對象創建、依賴管理、生命週期控制權從應用代碼移交給容器。本文深度解析 Spring IoC 容器的核心架構、BeanDefinition 註冊、依賴解析、生命週期管理、擴展點機制等核心原理。
BeanFactory (根接口)
├─ getBean(name) / getBean(type)
├─ containsBean(name)
├─ isSingleton(name) / isPrototype(name)
├─ getType(name)
└─ getAliases(name)
↓ 擴展
ListableBeanFactory
├─ getBeanNamesForType(type)
├─ getBeanNamesForAnnotation(annotation)
└─ getBeanDefinitionNames()
↓ 擴展
HierarchicalBeanFactory
├─ getParentBeanFactory()
└─ containsLocalBean(name)
↓ 擴展
ConfigurableBeanFactory (配置能力)
├─ registerSingleton(name, object)
├─ registerBeanDefinition(name, BeanDefinition)
├─ addBeanPostProcessor(processor)
├─ setClassLoader(classLoader)
├─ addPropertyEditorRegistrar(registrar)
└─ addEmbeddedValueResolver(resolver)
↓ 擴展
AutowireCapableBeanFactory (自動裝配)
├─ createBean(clazz)
├─ autowireBean(bean)
├─ initializeBean(bean, name)
├─ applyBeanPostProcessorsBeforeInitialization()
└─ applyBeanPostProcessorsAfterInitialization()
↓ 終極擴展
ApplicationContext (企業級上下文)
├─ 繼承以上所有
├─ getEnvironment() → EnvironmentCapable
├─ getMessage(code, args, locale) → MessageSource
├─ publishEvent(event) → ApplicationEventPublisher
├─ getResources(pattern) → ResourcePatternResolver
├─ start() / stop() → Lifecycle
└─ getId() / getDisplayName() → 身份標識
beanDefinitionMap:`ConcurrentHashMapsingletonObjects:`ConcurrentHashMapearlySingletonObjects:`ConcurrentHashMapsingletonFactories:`ConcurrentHashMapregisteredSingletons:`LinkedHashSetpublic class BeanDefinition {
// 基礎屬性
String beanClassName; // 全限定類名
String scope; // singleton / prototype / request / session
boolean lazyInit; // 延遲初始化
String factoryBeanName; // FactoryBean 名稱
String factoryMethodName; // 工廠方法名
// 依賴關係
ConstructorArgumentValues constructorArgumentValues; // 構造器參數
MutablePropertyValues propertyValues; // Setter 參數
String[] dependsOn; // 依賴的其他 Bean (強制初始化順序)
boolean autowireCandidate; // 是否作為自動裝配候選
boolean primary; // 優先自動裝配
// 生命週期
String initMethodName; // 初始化方法
String destroyMethodName; // 銷毀方法
// 運行時狀態
volatile Object beanClass; // 解析後的 Class 對象
boolean synthetic; // 內部合成 Bean (如 aop:config 生成)
int role; // ROLE_APPLICATION / ROLE_SUPPORT / ROLE_INFRASTRUCTURE
}
| 來源類型 | 解析器/處理器 | 典型場景 |
|---|---|---|
| XML <bean> | XmlBeanDefinitionReader → BeanDefinitionParserDelegate | 傳統 XML 配置 |
| @Component 掃描 | ClassPathBeanDefinitionScanner → AnnotatedBeanDefinitionReader | 註解驅動開發 |
| @Bean 方法 | ConfigurationClassPostProcessor → ConfigurationClassBeanDefinitionReader | Java Config |
| @Import | ImportBeanDefinitionRegistrar 實現類 | 模塊化配置、自動配置 |
| 動態註冊 | BeanDefinitionRegistryPostProcessor → registerBeanDefinition() | 框架擴展、條件註冊 |
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1. 準備階段:初始化屬性源、驗證必需屬性
prepareRefresh();
// 2. 核心:獲取/創建 BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. 配置 BeanFactory 標準上下文特性
prepareBeanFactory(beanFactory);
try {
// 4. 子類擴展點:後置處理 BeanFactory
postProcessBeanFactory(beanFactory);
// 5. 調用 BeanFactoryPostProcessor (關鍵擴展點)
invokeBeanFactoryPostProcessors(beanFactory);
// 6. 註冊 BeanPostProcessor (另一關鍵擴展點)
registerBeanPostProcessors(beanFactory);
// 7. 初始化消息源 (i18n)
initMessageSource();
// 8. 初始化事件廣播器
initApplicationEventMulticaster();
// 9. 子類擴展點:初始化特定 Bean (如 MVC 請求映射)
onRefresh();
// 10. 註冊監聽器
registerListeners();
// 11. 核心:預實例化所有非懶加載單例 Bean
finishBeanFactoryInitialization(beanFactory);
// 12. 完成刷新:發布 ContextRefreshedEvent、啟動 Lifecycle Bean
finishRefresh();
} catch (BeansException ex) {
// 銷毀已創建單例、發布 ContextClosedEvent
destroyBeans();
cancelRefresh(ex);
throw ex;
}
}
}
// 典型實現:ConfigurationClassPostProcessor (處理 @Configuration/@Bean/@ComponentScan)
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 1. 解析 @Configuration 類
// 2. 處理 @ComponentScan → 掃描組件 → 註冊 BeanDefinition
// 3. 處理 @Import → 導入配置類/ImportSelector/ImportBeanDefinitionRegistrar
// 4. 處理 @Bean 方法 → 註冊 BeanDefinition
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 處理 @PropertySource、@EnableAspectJAutoProxy 等
}
}
// PropertySourcesPlaceholderConfigurer:解析 ${...} 佔位符
// 自定義:實現 BeanFactoryPostProcessor 可在 Bean 實例化前修改 BeanDefinition
// 核心接口
public interface BeanPostProcessor {
// 初始化前:可返回代理對象、修改屬性
Object postProcessBeforeInitialization(Object bean, String beanName);
// 初始化後:AOP 代理創建、驗證、記錄日誌
Object postProcessAfterInitialization(Object bean, String beanName);
}
// 關鍵內建實現 (按優先級排序):
// 1. PriorityOrdered → Ordered → 無序
// 2. InstantiationAwareBeanPostProcessor (擴展:預實例化、屬性注入攔截)
// 3. DestructionAwareBeanPostProcessor (擴展:銷毀前回調)
// 典型應用:
// - AutowiredAnnotationBeanPostProcessor:處理 @Autowired/@Value/@Inject
// - CommonAnnotationBeanPostProcessor:處理 @PostConstruct/@PreDestroy/@Resource
// - PersistenceAnnotationBeanPostProcessor:處理 @PersistenceContext/@PersistenceUnit
// - AsyncAnnotationBeanPostProcessor:處理 @Async 創建代理
// - TransactionAnnotationBeanPostProcessor:處理 @Transactional 創建事務代理
// - AnnotationAwareAspectJAutoProxyCreator:AOP 代理創建核心
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 1. 初始化轉換服務
beanFactory.setConversionService(new DefaultConversionService());
// 2. 註冊內嵌值解析器 (解析 ${...} #{...})
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
// 3. 初始化 LoadTimeWeaver (AspectJ LTW)
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String name : weaverAwareNames) {
getBean(name); // 觸發實例化
}
// 4. 核心循環:預實例化所有非懶加載 singleton
beanFactory.preInstantiateSingletons();
}
getBean(beanName)
↓
1. 循環依賴檢查 (beforePrototypeCreation / afterPrototypeCreation)
↓
2. 合併 BeanDefinition (getMergedLocalBeanDefinition - 父子繼承合併)
↓
3. 依賴處理 (dependsOn → 遞歸初始化依賴 Bean)
↓
4. 作用域分發
├─ Singleton → getSingleton(beanName, () -> createBean(...))
├─ Prototype → createBean(beanName, bd, args)
├─ Request/Session/Application → 作用域特定獲取/創建
└─ Custom Scope → Scope.get(beanName, factory)
↓
5. createBean 核心流程 (Singleton 為例)
├─ createBeanInstance() → 實例化 (構造器/工廠方法/反射)
├─ populateBean() → 屬性填充 (Setter/自動裝配/@Value)
├─ initializeBean() → 初始化
│ ├─ Aware 接口回調 (BeanNameAware, BeanFactoryAware, ApplicationContextAware...)
│ ├─ BeanPostProcessor.postProcessBeforeInitialization()
│ ├─ 初始化方法調用 (InitializingBean.afterPropertiesSet() / @PostConstruct / init-method)
│ └─ BeanPostProcessor.postProcessAfterInitialization() → AOP 代理在此創建
└─ 註冊銷毀回調 (DisposableBean / @PreDestroy / destroy-method)
↓
6. 返回成品對象 (原始 Bean 或 代理對象)
// 單例模式下,A 依賴 B,B 依賴 A (Setter 注入)
步驟 1:A 實例化完成,放入三級緩存
singletonFactories.put("A", () -> getEarlyBeanReference("A", bd, bean));
// ObjectFactory 能返回早期引用 (若有 BeanPostProcessor 可能返回代理)
步驟 2:A 屬性填充,需要 B → getBean("B")
↓ B 實例化、屬性填充,需要 A → getBean("A")
步驟 3:getBean("A") 從三級緩存獲取
ObjectFactory> factory = singletonFactories.get("A");
if (factory != null) {
Object earlyRef = factory.getObject(); // 獲取早期引用 (可能是代理)
earlySingletonObjects.put("A", earlyRef); // 升級到二級緩存
singletonFactories.remove("A"); // 從三級移除
return earlyRef;
}
步驟 4:B 完成初始化,持有 A 的早期引用
步驟 5:A 完成初始化,從二級緩存獲取自身,放入一級緩存
singletonObjects.put("A", bean);
earlySingletonObjects.remove("A");
registeredSingletons.add("A");
關鍵點:僅支援 單例 + Setter/字段注入 的循環依賴。構造器注入無法解決 (需打破循環或使用 @Lazy)。Prototype 作用域不支援循環依賴。
// 在 BeanPostProcessor.postProcessAfterInitialization() 中
public class AnnotationAwareAspectJAutoProxyCreator extends AbstractAutoProxyCreator {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey); // 創建代理
}
}
return bean;
}
}
// wrapIfNecessary() 核心邏輯:
// 1. 獲取目標類的所有切面 (Advisor)
// 2. 構建 ProxyFactory
// 3. 選擇代理方式:JDK Dynamic Proxy (實現接口) vs CGLIB (繼承類)
// 4. 返回目標對象的代理
| 擴展點接口 | 調用時機 | 典型用途 | 實現示例 |
|---|---|---|---|
| BeanFactoryPostProcessor | BeanDefinition 註冊完成,Bean 實例化前 | 修改 BeanDefinition、掃描註冊、解析佔位符 | ConfigurationClassPostProcessor, PropertySourcesPlaceholderConfigurer |
| BeanDefinitionRegistryPostProcessor | BeanFactoryPostProcessor 之前 | 動態註冊 BeanDefinition | ConfigurationClassPostProcessor, 自定義註冊器 |
| BeanPostProcessor | Bean 初始化前/後 | AOP 代理、依賴注入、驗證、修改屬性 | AutowiredAnnotationBPP, AsyncAnnotationBPP, AnnotationAwareAspectJAutoProxyCreator |
| InstantiationAwareBeanPostProcessor | 實例化前/後、屬性注入前 | 返回代理跳過默認實例化、攔截屬性注入 | ConfigurationClassEnhancer (CGLIB 代理 @Configuration) |
| SmartInstantiationAwareBeanPostProcessor | 預測 Bean 類型、確定構造器 | 優化自動裝配性能 | 內部優化使用 |
| FactoryBean | getBean() 時調用 getObject() | 封裝複雜對象創建邏輯 | SqlSessionFactoryBean, LocalContainerEntityManagerFactoryBean |
| InitializingBean / @PostConstruct | 屬性填充完成後 | 業務初始化邏輯 (連接池預熱、緩存加載) | 自定義 Service 初始化 |
| DisposableBean / @PreDestroy | 容器關閉前 | 資源釋放 (關閉連接、線程池關閉) | DataSource 銷毀、Scheduler 關閉 |
| ApplicationListener / @EventListener | 事件發布時 | 業務解耦、異步處理 | 用戶註冊發送郵件、訂單創建發送 MQ |
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class) // 關鍵:導入自動配置類
public @interface EnableAutoConfiguration { }
// AutoConfigurationImportSelector.selectImports()
public String[] selectImports(AnnotationMetadata annotationMetadata) {
// 1. 讀取 META-INF/spring.factories
// 2. 獲取 EnableAutoConfiguration 對應的所有配置類
// 3. 過濾:@ConditionalOnClass/@ConditionalOnMissingBean/@ConditionalOnProperty...
// 4. 排序:@AutoConfigureOrder / @AutoConfigureBefore/After
// 5. 返回全限定類名數組
}
@Configuration
@ConditionalOnClass(DataSource.class) // 類路徑存在 DataSource
@ConditionalOnMissingBean(DataSource.class) // 容器無 DataSource Bean
@ConditionalOnProperty(prefix="spring.datasource", name="url") // 配置了 url
@EnableConfigurationProperties(DataSourceProperties.class) // 綁定配置屬性
public class DataSourceAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public DataSource dataSource(DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().build(); // HikariCP 優先
}
}
Spring IoC 容器的核心價值在於:將「對象創建與裝配」從業務代碼中剝離,通過標準化的生命週期、擴展點、元數據模型,構建出高度可擴展、可維護的企業級應用框架。
掌握 BeanDefinition 元數據模型、refresh() 啟動流程、三級緩存解決循環依賴、BeanPostProcessor 擴展機制、條件裝配原理,是從「使用 Spring」進階為「精通 Spring」的必經之路。這些原理不僅指導日常開發排查疑難雜症,更是設計高質量框架、中間件的理論基石。