依賴注入(DI):讓元件依賴抽象(介面),具體實現由容器在執行期注入,實現鬆耦合。Spring 提供三種注入方式,本質皆是「由外部決定依賴關係」。
定義注入介面,被注入類別必須實作該介面。容器透過介面方法注入依賴。
// 1. 定義注入介面
public interface IBusiness {
void createDI(DataBase db);
}
// 2. 業務類實作介面
public class Business implements IBusiness {
private DataBase db;
public void createDI(DataBase db) { this.db = db; } // 介面方法注入
public void getData() { db.getData(); }
}
// 3. 使用端
public class TestBusiness {
private Business business = new Business();
public void getData() {
business.createDI(new OracleDataBase()); // 手動注入(或由容器調用)
business.getData();
}
}
特點:強制實作介面、侵入性強、現代 Spring 較少使用(Spring 核心不直接支援,需自行實作回調)。
提供 setXxx() 方法,容器透過反射呼叫 setter 注入依賴。Spring 最推薦、最靈活 的方式。
public class Business {
private DataBase db;
public void setDataBase(DataBase db) { this.db = db; } // Setter 注入點
public void getData() { db.getData(); }
}
XML 配置:
<bean id="business" class="com.demo.Business">
<property name="dataBase" ref="oracleDataBase"/>
</bean>
<bean id="oracleDataBase" class="com.demo.OracleDataBase"/>
優點:可選依賴(可為 null)、支援循環依賴、可重新配置、可讀性高。
透過建構子參數注入,建構子完成後物件即處於完全初始化狀態。適合強制依賴、不可變物件。
public class Business {
private final DataBase db; // final 不可變
public Business(DataBase db) { this.db = db; } // 建構子注入
public void getData() { db.getData(); }
}
XML 配置:
<bean id="business" class="com.demo.Business">
<constructor-arg ref="oracleDataBase"/>
</bean>
優點:不可變性、執行緒安全、依賴不可為 null、IDE 友善(建構子參數明確)。
| 維度 | 介面注入 | Setter 注入 | 建構子注入 |
|---|---|---|---|
| 侵入性 | 高(須實作介面) | 低(POJO) | 低(POJO) |
| 依賴可選性 | 否 | 是(可為 null) | 否(必須提供) |
| 循環依賴支援 | 困難 | 良好 | 需配合 @Lazy |
| 不可變性 | 否 | 否 | 是(配合 final) |
| Spring 推薦度 | 低 | 高(傳統) | 高(現代最佳實踐) |
@RequiredArgsConstructor 自動產生建構子,減少樣板碼。