控制反轉 不是技術,是設計思想。傳統開發中,對象主動
new依賴 (主動權在自己);IOC 容器接管對象創建與裝配,對象被動接受依賴 (主動權轉移給容器)。
好萊塢法則:「別調用我們,我們會調用你」—— 容器負責調度,組件只需暴露依賴接口。
| 維度 | IOC (控制反轉) | DI (依賴注入) |
|---|---|---|
| 關注點 | 誰控制對象生命周期 | 依賴關係如何賦值 |
| 描述角度 | 容器視角 | 組件視角 |
| 核心動作 | 容器創建、管理、銷毀 Bean | 容器將依賴「注入」組件 |
| Martin Fowler 命名 | 概念較模糊 | 2004 年明確命名,更具體 |
結論:IOC 是架構層面的宏觀概念,DI 是實現 IOC 的具體技術手段 (Setter/構造器/字段注入)。
applicationContext.xml / 掃描 @Component / 解析 @Configuration。BeanDefinition 註冊到 BeanDefinitionRegistry (Map<String, BeanDefinition>)。PropertyPlaceholderConfigurer 解析 ${...}、ConfigurationClassPostProcessor 解析註解配置類。InstantiationStrategy (CGLIB/字節碼) 創建 Bean 實例。BeanDefinitionValueResolver 解析引用、集合、屬性值,調用 Setter/字段注入。AutowiredAnnotationBeanPostProcessor 處理 @Autowired、@Value;AOP 代理創建。InitializingBean.afterPropertiesSet()、@PostConstruct、自定義 init-method。DisposableBean、@PreDestroy、destroy-method。singletonObjects,應用程序可用。| 方式 | 代碼示例 | 優點 | 缺點 | 推薦場景 |
|---|---|---|---|---|
| 構造器注入 | @Autowired public Service(Repo repo) {} | 不可變性、強依賴檢查、易測試 (無 Spring 也能 new) | 循環依賴難處理、參數多啰嗦 | 首選,所有強依賴 |
| Setter 注入 | @Autowired public void setRepo(Repo repo) {} | 可選依賴、解決循環依賴、可重新配置 | 對象可能處於不完整狀態、破壞封裝 | 可選依賴、第三方庫集成 |
| 字段注入 | @Autowired private Repo repo; | 代碼極簡 | 反射強行賦值、不可測試、隱藏依賴、最終字段無效 | 禁止 生產代碼 (僅測試類可用) |
getBean() 創建新實例,Spring 不管理銷毀,需自行釋放資源。