Dagger-快速依賴注入器
這個架構它的好處是它沒有采用反射技術(Spring是用反射的),而是用預編譯技術,因為基于反射的DI非常地耗用資源(空間,時間)。這裡記錄一下上面文章的一些關鍵的要點
聲明依賴關系
Dagger 構造應用程式的類對象,并組合其依賴關系。 Dagger使用
javax.inject.Inject
annotation 标記那些需要依賴注入的構造函數和成員變量。
Dagger将使用
@Inject 注釋的構造函數
建立類對象。 當請求建構新的類對象時, Dagger 将自動擷取相應的參數, 并調用構造函數。
class Thermosiphon implements Pump {
private final Heater heater;
@Inject
Thermosiphon(Heater heater) {
this.heater = heater;
}
...
}
class CoffeeMaker {
@Inject Heater heater;
@Inject Pump pump;
...
}
Dagger 可以直接注入成員變量。在這個例子中, 它擷取Heater對象, 并注入到成員變量heater, ,擷取Pump對象并注入到成員變量pump。
注意,當類中含有@Inject注釋的成員變量, 卻沒有@Inject注釋的構造函數時, Dagger将使用類的預設構造函數。若類中缺少@Inject注釋, 該類是不能由Dagger建立的。這這個例子中,因為Thermosiphon類中有@Inject注釋的構造函數,當有數要建構這個類對象的時候,就使用這個@Inject注釋的構造函數來建構類的對象。
Dagger不支援函數注入。
實作依賴關系
預設情況下, Dagger 通過構造相應類型的對象來實作依賴關系。當請求一個CoffeMaker對象時, Dagger将調用new CoffeeMaker()構造函數, 并指派給@Inject标記的成員變量。
但是@Inject并不是在任何情況下都可以:
- 接口類型不能被構造
- 第三方的類不能被注釋構造。
- 可配置的對象必須被配置好
對那些使用@Inject效率極低的情況, 可以使用@Provides注釋函數來實作依賴關系。這些函數的傳回類型定義其實作的依賴關系。
例如, 當需要一個Heater時, Dagger将調用provideHeater()函數擷取。
@Provides Heater provideHeater() {
return new ElectricHeater();
}
@Provides注釋的函數也可以有他們自己的依賴關系。下面這個Provides函數依賴于一個Thermosiphon對象:
@Provides Pump providePump(Thermosiphon pump) {
return pump;
}
所有的@Provides函數必須屬于一個Module。這些Module類使用@Module注釋。
@Module
class DripCoffeeModule {
@Provides Heater provideHeater() {
return new ElectricHeater();
}
@Provides Pump providePump(Thermosiphon pump) {
return pump;
}
}
注意,通常情況下, 約定@Provides函數以provide作為字首, @Module類以Module作為字尾。
建構ObjectGraph(對象圖表)
@Inject 和 @Provides 注釋的類建構了一個對象圖表。這些對象與對象之間通過依賴關系互相關聯。通過函數
ObjectGraph.create()
擷取這個對象圖表, 這個函數可以接受一個或多個Module作為參數:
ObjectGraph objectGraph = ObjectGraph.create(new DripCoffeeModule());