原文鏈接:http://google.github.io/dagger/users-guide.html
從Why Dagger 2 is Different 開(kāi)始翻譯赫悄。
為什么Dagger2是不同的
依賴注入的框架在幾年前就已經(jīng)存在了钧栖,有許多中API實(shí)現(xiàn)了依賴和注入。為什么要重復(fù)造輪子呢?Dagger2是第一個(gè)實(shí)現(xiàn)了全部代碼生成菇篡。它的目標(biāo)原則是模仿用戶那些手寫(xiě)的代碼(實(shí)現(xiàn)依賴注入的代碼)使依賴注入的過(guò)程實(shí)現(xiàn)起來(lái)更加簡(jiǎn)單煞额。
使用Dagger2
我們將通過(guò)CoffeeMaker的例子證明Dagger的依賴注入。已經(jīng)完成的代碼可以從coffee example查看荒吏,并進(jìn)行編譯和運(yùn)行敛惊。
聲明依賴
使用Dagger為你的應(yīng)用類構(gòu)造實(shí)例,并且滿足它們的依賴绰更。Dagger使用 javax.inject.Inject
注解標(biāo)明哪些構(gòu)造方法和參數(shù)是需要注解的瞧挤。
使用@Inject注解一個(gè)構(gòu)造方法表示應(yīng)該用Dagger為這個(gè)類創(chuàng)建一個(gè)實(shí)例锡宋。當(dāng)一個(gè)請(qǐng)求為該對(duì)象創(chuàng)建一個(gè)新的實(shí)例時(shí),Dagger會(huì)獲得請(qǐng)求的參數(shù)值然后執(zhí)行該構(gòu)造方法特恬。
class Thermosiphon implements Pump {
private final Heater heater;
@Inject
Thermosiphon(Heater heater) {
this.heater = heater;
}
...
}
Dagger也可以直接注解參數(shù)执俩,在這個(gè)例子中將為一個(gè)heater對(duì)象獲得一個(gè) Heater實(shí)例,為pump對(duì)象獲得一個(gè)Pump實(shí)例癌刽。
class CoffeeMaker {
@Inject
Heater heater;
@Inject
Pump pump;
...}
如果你用@inject標(biāo)注了參數(shù)役首,但沒(méi)有用@inject標(biāo)注方法。當(dāng)有請(qǐng)求到這些參數(shù)的時(shí)候显拜,Dagger會(huì)為這些對(duì)象提供注入衡奥,但不會(huì)為他們創(chuàng)建實(shí)例。用@inject標(biāo)注一個(gè)無(wú)參的構(gòu)造函數(shù)远荠,以表明Dagger也可以創(chuàng)建一個(gè)實(shí)例矮固。
Dagger同樣也支持方法的注入,盡管通常情況下優(yōu)先考慮的是參數(shù)和構(gòu)造方法矮台。
如果一個(gè)類缺乏@Inject是不能通過(guò)Dagger構(gòu)建的
滿意的依賴
默認(rèn)情況下乏屯,Dagger通過(guò)構(gòu)造請(qǐng)求類型對(duì)象的實(shí)例滿足每一個(gè)依賴。像上面描述(例子)的那樣瘦赫,當(dāng)你請(qǐng)求(需要)一個(gè)CoffeeMaker對(duì)象辰晕,你將通過(guò)調(diào)用new Caffee()對(duì)象獲得一個(gè)對(duì)象,注入到可以注入的參數(shù)中确虱。
但是@Inject不是任何對(duì)象都可以標(biāo)記的
- interface是不能被構(gòu)建的
- 第三方的類不能被注解
- 通過(guò)配置得到的對(duì)象含友,仍然必須通過(guò)配置得到(Builder模式構(gòu)造的對(duì)象)
在這些情況下,@Inject是不足的(尷尬的)校辩,但是可以通過(guò)使用@Provide注解標(biāo)注的方法來(lái)滿足依賴窘问,這個(gè)方法的返回值的來(lái)滿足那些依賴。
就像下面這樣:當(dāng)需要一個(gè)Heater對(duì)象時(shí)provideHeater()方法會(huì)被執(zhí)行宜咒。
@Provides
static Heater provideHeater() {
return new ElectricHeater();
}
@Provides同樣可以為它自己提供依賴惠赫,當(dāng)我們需要一個(gè)Pump對(duì)象時(shí),下面這個(gè)例子返回一個(gè)Thermosiphon對(duì)象時(shí)
@Provides
static Pump providePump(Thermosiphon pump) {
return pump;
}
所有被標(biāo)注了@Provides注解的方法必須要屬于一個(gè)module類(模塊)故黑,這僅僅需要一個(gè)類被@module注解標(biāo)注儿咱。
@Module
class DripCoffeeModule {
@Provides
static Heater provideHeater() {
return new ElectricHeater();
}
@Provides
static Pump providePump(Thermosiphon pump) {
return pump;
}
}
注:通常@Provides標(biāo)注的方法名都擁有provide前綴,@Module標(biāo)注的類都有一個(gè)叫做Module的后綴场晶。
構(gòu)建對(duì)象關(guān)系圖
@Inject注解和@Provides注解類由他們之間的依賴關(guān)系形成了對(duì)關(guān)系的圖混埠,通過(guò)一組定義好的關(guān)系圖調(diào)用代碼就像使用應(yīng)用程序的main方法或者Android的應(yīng)用程序訪問(wèn)。它的定義是通過(guò)一個(gè)接口:具備無(wú)參的方法和需要的返回值類型诗轻。通過(guò)使用@component注解去標(biāo)注這樣一個(gè)接口和通過(guò)module參數(shù)去配置module類型钳宪,Dagger2隨后會(huì)生成一個(gè)符合的實(shí)現(xiàn)。
@Component(modules = DripCoffeeModule.class)
interface CoffeeShop {
CoffeeMaker maker();
}
Dagger2會(huì)自動(dòng)為它生成實(shí)現(xiàn)類,實(shí)現(xiàn)的名字是具有Dagger的前綴加上接口的名稱吏颖。通過(guò)使用builder方法獲得實(shí)例搔体。調(diào)用Builder方法配置依賴,調(diào)用build方法獲得實(shí)例侦高。
CoffeeShop coffeeShop = DaggerCoffeeShop.builder() .dripCoffeeModule(new DripCoffeeModule()) .build();