IoC(控制反轉):將物件創建與依賴管理權移交給容器,實現鬆耦合。容器負責查找、創建、注入依賴,應用程式僅被動接受。體現「好萊塢法則」——「別找我們,我們找你」。
<beans>
<bean id="test" class="org.study.spring.ioc.Test"/>
</beans>
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
Test bean = ctx.getBean("test", Test.class);
關鍵步驟:
obtainFreshBeanFactory() 建立 BeanFactoryinvokeBeanFactoryPostProcessors(beanFactory) 執行 BeanDefinition 後處理器(如 PropertyPlaceholderConfigurer、ConfigurationClassPostProcessor)registerBeanPostProcessors(beanFactory) 註冊 BeanPostProcessorfinishBeanFactoryInitialization(beanFactory) 預實例化所有非延遲單例 BeanPostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors() 按優先級分三批執行:
PriorityOrdered 的 BeanDefinitionRegistryPostProcessorOrdered 的 BeanDefinitionRegistryPostProcessorBeanDefinitionRegistryPostProcessor,以 while 迴圈直至無新增隨後同樣優先級順序執行一般 BeanFactoryPostProcessor,最後清理元資料快取。
三階段策略:
singletonObjects、earlySingletonObjects、singletonFactories(解決循環依賴)depends-on) → 根據 scope 創建(單例用 getSingleton() 雙重檢查鎖,原型直接 createBean())四階段:
lookup-method、replaced-method)resolveBeforeInstantiation() 讓 BeanPostProcessor 有機會返回代理物件(如 AOP)doCreateBean() 完成實際創建與初始化按優先級選擇:
factory-method)autowire=constructor 或有 constructor-arg)SimpleInstantiationStrategy 使用反射 clazz.getDeclaredConstructor())若有 @Lookup 或 @Replace,會動態生成 CGLIB 子類。
處理 @Autowired、@Value、XML property 等,支援類型轉換、集合合併、延遲注入等。
BeanNameAware、BeanClassLoaderAware、BeanFactoryAware 等BeanPostProcessor.postProcessBeforeInitialization()InitializingBean.afterPropertiesSet()init-method 指定的方法BeanPostProcessor.postProcessAfterInitialization()(AOP 代理在此生成)registerDisposableBeanIfNecessary() 針對單例註冊銷毀回調(DisposableBean.destroy() 或 destroy-method),容器關閉時執行。
getBean()
└─ doGetBean()
├─ 緩存檢查 / 父工廠委派
└─ createBean()
├─ resolveBeforeInstantiation() → BeanPostProcessor 早期代理
└─ doCreateBean()
├─ createBeanInstance() → 反射/CGLIB/工廠方法
├─ populateBean() → 依賴注入
├─ initializeBean()
│ ├─ invokeAwareMethods()
│ ├─ applyBeanPostProcessorsBeforeInitialization()
│ ├─ invokeInitMethods() → afterPropertiesSet / init-method
│ └─ applyBeanPostProcessorsAfterInitialization() → AOP 代理
└─ registerDisposableBeanIfNecessary()
掌握此流程可精準定位 Bean 生命週期問題,並理解 Spring 如何實現鬆耦合與擴展點開放。