在企業級應用開發中,降低模塊間耦合是提升系統可維護性、可擴展性、可測試性的關鍵。控制反轉 (Inversion of Control, IoC) 作為一種設計思想,通過將對象創建與依賴管理的控制權從應用代碼轉移到外部容器,實現了解耦。依賴注入 (Dependency Injection, DI) 是 IoC 的具體實現方式。本文從核心概念、實現策略、三種調用模式演進、實戰代碼示例四個維度深度剖析。
| 概念 | 全稱 | 核心含義 | 關鍵點 |
|---|---|---|---|
| IoC | Inversion of Control | 控制權反轉:對象創建、依賴查找、生命周期管理由容器接管 | 思想/模式,非具體技術 |
| DI | Dependency Injection | 依賴注入:容器主動將依賴對象「推」入被依賴對象(構造器/Setter/接口) | IoC 的具體實現策略 |
本質:控制權從應用代碼轉移到外部容器 → 依賴關系由容器在運行期動態構建 → 實現調用者與被調用者的解耦。
Context.lookup("serviceName")。場景:Student(調用者)學習 Book(被調用者,接口 IBook,實現 BookA、BookB)。
public class Student {
public void learnBookA() { new BookA().learn(); }
public void learnBookB() { new BookB().learn(); }
}
public class BookFactory {
public static IBook getBookA() { return new BookA(); }
public static IBook getBookB() { return new BookB(); }
}
public class Student {
public void learnBookA() { BookFactory.getBookA().learn(); }
public void learnBookB() { BookFactory.getBookB().learn(); }
}
public class Student {
// 構造器注入
private final IBook book;
public Student(IBook book) { this.book = book; }
public void learn() { book.learn(); }
}
// 外部組裝(容器或手動)
IBook bookA = new BookA();
IBook bookB = new BookB();
Student student = new Student(bookA); // 或 setBook(bookB)
student.learn();
IBook。外部組裝者決定用哪個實現,實現完全解耦、可測試、可替換。<bean id="bookA" class="com.example.BookA"/> <bean id="bookB" class="com.example.BookB"/> <bean id="student" class="com.example.Student"> <constructor-arg ref="bookA"/> <!-- 構造器注入 --> <!-- <property name="book" ref="bookB"/> --> <!-- Setter 注入 --> </bean>
@Component("bookA") public class BookA implements IBook { ... }
@Component("bookB") public class BookB implements IBook { ... }
@Component
public class Student {
private final IBook book;
@Autowired // 構造器注入,單構造器可省略
public Student(@Qualifier("bookA") IBook book) { this.book = book; }
public void learn() { book.learn(); }
}
啟用掃描:@ComponentScan("com.example") 或 XML <context:component-scan base-package="com.example"/>。
@Lazy 或重構設計打破循環。IoC/DI 不是花哨的框架特性,而是「面向接口編程」+「工廠模式」+「配置元數據」的工程化落地。Spring 容器將這套機制標準化、自動化,讓開發者專注領域邏輯。理解其本質——控制權反轉、依賴外部注入、面向抽象編程,才能在架構設計、故障排查、性能調優中遊刃有餘。