Dagger2使用

---

##概述

依賴注入(Dependency Injection),簡稱DI,又叫控制反轉(Inversion of Control),簡稱IOC。Dagger2就是DI框架的一個例子。

---

##作用

將各層的對象以松耦合的方式組織在一起,解耦,各層對象的調用完全面向接口。

---

##提供依賴的兩種方式

###使用@Inject注解構造器

```javaclass Thermosiphon implements Pump {private final Heater heater;@InjectThermosiphon(Heater heater) {this.heater = heater;}}```

###使用@Module```java@Moduleclass DripCoffeeModule {@Provides static Heater provideHeater() {return new ElectricHeater();}@Provides static Pump providePump(Thermosiphon pump) {return pump;}}```**使用@Module替代@Inject的情況有:**-依賴是一個接口,不能使用構造器。-依賴是第三方類,不能添加@Inject注解。-依賴在使用前需要被配置。---##注入依賴的兩種方式使用@Inject和@Provides注解的類對象組成了一個有向圖(graph),該圖的頂點(vertex)由它們的依賴參數連接。我們可以通過@Component注解的接口來訪問這個有向圖。我們將Module傳遞給@Component的modile參數,Dagger2負責生成一個該接口的實現類,事實上構建一個Component的過程就是在構建一個graph。任何具有默認構造器的Module都不需要顯示地設置,builder會自動的創建Module。```javaCoffeeShop coffeeShop = DaggerCoffeeShop.builder().dripCoffeeModule(new DripCoffeeModule()).build();```可簡化成:```javaCoffeeShop coffeeShop = DaggerCoffeeShop.builder().build();```如果所需的依賴不需要構造Module就能提供(@Provides方法是靜態的),那么實現類會提供一個create()方法來快速的獲取一個Component實例。```javaCoffeeShop coffeeShop = DaggerCoffeeShop.create();```Component中可以可以包含兩種方法。分別為:-Provision Mothod-Members-injection MethodProvision Method沒有參數并且返回需要的類型。Members-injection Method一般沒有返回值,參數是需要注入成員變量的類(一般命名為inject)。---##依賴的來源-Module中通過@Provides注解的方法;Component通過@Component.modules直接引用,如果Module中通過@Module,include定義了子Module,也一并包括。-使用@Inject注解構造器的類(沒有使用@Scope或者@Scope同Component一致)-該Component依賴的Component的Provision Method-該Component本身-subComponent的未限定builder-以上依賴的Provider或者Lazy包裝類。-以上依賴的Lazy包裝類的Provider包裝類(如Provider)---##單例和作用域Component只會識別未加作用域或者作用域和自己一致的依賴。所以如果@Provids和可注入類加上了作用域,那么Component一定要加上作用域(和@Provide作用域一致的@Scope進行注解)。##Component的dependencies---Component不僅僅可以有modules也可以有dependencies。也就是依賴其他的Component。```java@Component(dependencies = ApplicationComponent.class, modules = ActivityModule.class)@PerActivitypublic interface ActivityComponent {void inject(MainActivity mainActivity);}```注意:只有被依賴的Component中的Provisoin Method才會參與到該Component代表的有向圖構建。也就是說只有Provison Method返回的依賴才可以被初始化。---##\#SubComponentComponent可以依賴其他Component,dependence是實現其方式之一,也可以使用SubComponent。卻別在于dependence必須明顯的顯示依賴關系,而SubComponent不必明確的定義依賴關系。舉個例子說明一下:```java@Modulepublic class ModuleA {@Providespublic SomeClassA1 provideSomeClassA1() {return new SomeClassA1();}}@Modulepublic class ModuleB {@Providespublic SomeClassB1 provideSomeClassB1(SomeClassA1 someClassA1) {return new SomeClassB1(someClassA1);}}public class SomeClassA1 {public SomeClassA1() {}}public class SomeClassB1 {private SomeClassA1 someClassA1;public SomeClassB1(SomeClassA1 someClassA1) {this.someClassA1 = someClassA1;}}```通過 provideSomeClassB1 可以看出SomeClassB1依賴SomeClassA1先來看一下用dependence的方式實現```javapublic class ComponentDependency {@Component(modules = ModuleA.class)public interface ComponentA {SomeClassA1 someClassA1();}@Component(modules = ModuleB.class, dependencies = ComponentA.class)public interface ComponentB {SomeClassB1 someClassB1();}public static void main(String[] args) {ModuleA moduleA = new ModuleA();ComponentA componentA = DaggerComponentDependency_ComponentA.builder().moduleA(moduleA).build();ModuleB moduleB = new ModuleB();ComponentB componentB = DaggerComponentDependency_ComponentB.builder().moduleB(moduleB).componentA(componentA).build();}}```SomeClassB1依賴SomeClassA1,ComponentB必須明確的定義dependencies,而ComponentA不需要聲明ModuleB(modules)。SubComponent實現方式:```javapublic class SubComponent {@Component(modules = {ModuleA.class, ModuleB.class})public interface ComponentA {ComponentB componentB(ModuleB moduleB);}@Subcomponent(modules = ModuleB.class)public interface ComponentB {SomeClassB1 someClassB1();}public static void main(String[] args) {ModuleA moduleA = new ModuleA();ModuleB moduleB = new ModuleB();ComponentA componentA = DaggerSubComponent_ComponentA.builder().moduleA(moduleA).moduleB(moduleB).build();ComponentB componentB = componentA.componentB(moduleB);}}```SomeClassB1依賴SomeClassA1,ComponentB不需要聲明依賴,,而ComponentA則需要聲明ModuleB(modules),并且ComponentA必須返回@Subcomponent。---##\#可釋放的引用使用 Scope 注解時,Component 會間接持有綁定的依賴實例的引用,也就是說實例在 Component 還存活時無法被回收。這時可以用@CanReleaseReferences標記 Scope 注解:```java@Documented@Retention(RUNTIME)@CanReleaseReferences@Scopepublic @interface MyScope {}```然后在 Application 中注入ReleasableReferenceManager對象,在內存不足時調用releaseStrongReferences()方法把 Component 間接持有的強引用變為弱引用。```javapublic class MyApplication extends Application {@Inject@ForReleasableReferences(MyScope.class)ReleasableReferenceManager myScopeReferences;@Overridepublic void onLowMemory() {super.onLowMemory();myScopeReferences.releaseStrongReferences();}...}```這樣在內存不足時,DaggerCoffeeShop 間接持有的變 實例為弱引用,如果沒有其他對象使用的話就可以被回收。##\#Lazy (延遲注入)有時我們想注入的依賴在使用時再完成初始化,加快加載速度,就可以使用注入Lazy。只有在調用 Lazy的 get() 方法時才會初始化依賴實例注入依賴。```javapublic class Main {@InjectLazy lazyMaker;public void goWork() {...lazyMaker.get(); // lazyMaker.get() 返回 CoffeeMaker 實例...}}```##\#Provider 注入有時候不僅僅是注入單個實例,我們需要多個實例,這時可以使用注入Provider,每次調用它的 get() 方法都會調用到 @Inject 構造函數創建新實例或者 Module 的 provide 方法返回實例。```javapublic class Main {@InjectProvider providerMaker;public void goWork() {...List makerList = new ArrayList(num);for (int i = 0; i < num; i ++) {makerList.add(providerMaker.get());}return makerList;...}}```----##\#限定符(Qualifiers)解決接口或者抽象類不足以描述一個依賴的問題```java@Qualifier@Retention(RetentionPolicy.RUNTIME)public @interface BananaFruit {}``````java@Qualifier@Retention(RetentionPolicy.RUNTIME)public @interface AppleFruit {}```加在所有你想返回確切class的地方。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內容