在軟體工程中,依賴注入(Dependency Injection,簡稱 DI)已成為提升程式碼可維護性、可測試性與彈性的關鍵模式。Google Guice 作為一個輕量級的 DI 框架,以「簡單易用」著稱,讓開發者能輕鬆管理物件之間的依賴關係,專注於業務邏輯而非繁瑣的工廠程式碼。
假設我們開發一個超級英雄應用,FrogMan 直接實例化 FrogMobile,而後者又依賴 HeavyWaterRefinery。單元測試時,若無法構建這些複雜依賴,測試將失敗或變得極其緩慢。
引入 Vehicle 介面,並透過建構子注入依賴:
public class FrogMan {
private Vehicle vehicle;
@Inject
public FrogMan(Vehicle vehicle) {
this.vehicle = vehicle;
}
}
測試時只需提供 MockVehicle 實作,完全避開真實依賴的啟動成本。
Guice 支援三種注入方式:
final 欄位。透過 Module 告訴 Guice 如何解析依賴:
public class HeroModule implements Module {
public void configure(Binder binder) {
binder.bind(Vehicle.class).to(FrogMobile.class);
binder.bind(Vehicle.class).annotatedWith(Fast.class).to(WeaselCopter.class);
}
}
支援 @Named 或自訂綁定註解(如 @Fast)區分同一介面的多種實作。
Injector injector = Guice.createInjector(new HeroModule());
FrogMan hero = injector.getInstance(FrogMan.class);
Guice 會遞歸解析 FrogMan → FrogMobile → FuelSource 的完整依賴鏈,實現「海龜疊海龜」的自動裝配。
在 Module 中使用 @Provides 編寫自訂建立邏輯:
@Provides
private Hero provideHero(FrogMan frogMan, WeaselGirl weaselGirl) {
return Math.random() > 0.5 ? frogMan : weaselGirl;
}
注入 Provider<T> 可延遲實例化或按需多次創建實例。
透過 Names.bindProperties(binder, properties) 從屬性檔讀取配置(如授權金鑰),避免硬編碼:
// HeroModule
private void loadProperties(Binder binder) {
Properties props = new Properties();
props.load(getClass().getResourceAsStream("/app.properties"));
Names.bindProperties(binder, props);
}
// app.properties
LicenseKey=QWERTY1234
Module。@Provides 整合第三方庫或複雜建構邏輯。Injector 手動獲取實例,逐步重構。Guice 以極簡的 API 實現了強大的依賴管理,讓 DI 真正落地為「簡單、有趣、可測試」的開發體驗。立即下載 Guice 2.0 體驗輕量級依賴注入的魅力吧!