Dagger2

什么是dagger2

Dagger是為Android和Java平臺(tái)提供的一個(gè)完全靜態(tài)的,在編譯時(shí)進(jìn)行依賴注入的框架膳汪,原來(lái)是由Square公司維護(hù)芒珠,現(xiàn)在由Google維護(hù)。一句話缨伊,dagger2其實(shí)就是一套依賴注入框架。那么什么是依賴注入呢进宝?
具體含義是:當(dāng)某個(gè)角色(可能是一個(gè)Java實(shí)例刻坊,調(diào)用者)需要另一個(gè)角色(另一個(gè)Java實(shí)例,被調(diào)用者)的協(xié)助時(shí)党晋,在 傳統(tǒng)的程序設(shè)計(jì)過(guò)程中谭胚,通常由調(diào)用者來(lái)創(chuàng)建被調(diào)用者的實(shí)例。但在dagger2里未玻,創(chuàng)建被調(diào)用者的工作不再由調(diào)用者來(lái)完成灾而,而是由dagger2來(lái)完成,然后注入調(diào)用者扳剿,因此也稱為依賴注入旁趟。

為什么需要dagger2

說(shuō)實(shí)話,剛接觸dagger2的時(shí)候我也是一臉懵逼庇绽,這個(gè)東西這么繁瑣锡搜,為什么要用它呢?這個(gè)問(wèn)題其實(shí)就是為何我們需要依賴注入瞧掺。有本書上這樣寫道:依賴注入不是目的耕餐,它是一系列工具和手段,最終的目的是幫助我們開發(fā)出松散耦合辟狈、可維護(hù)肠缔、可測(cè)試的代碼和程序∩仙拢可想而知桩砰,其最終目的是實(shí)現(xiàn)解耦。何為解耦释簿?怎么解耦亚隅?舉個(gè)例子說(shuō)明一下:
前面我們講到MVP架構(gòu),我們的Presenter層構(gòu)造函數(shù)可能需要一些參數(shù):訪問(wèn)服務(wù)端的AbsService實(shí)例庶溶,做網(wǎng)絡(luò)請(qǐng)求線程切換的SchedulerProvider 煮纵,如下,

public class TestPresenter extends BasePresenter<TestView> {
    AbsService mAbsService;
    SchedulerProvider mSchedulerProvider;

    public TestPresenter(AbsService absService,SchedulerProvider schedulerProvider) {
        this.mAbsService=absService;
        this.mSchedulerProvider=schedulerProvider;
    }
}

那么我們?cè)趯?shí)例化這個(gè)Presenter的時(shí)候就需要這樣做:

        AbsService mAbsService=AbsService.getInstance();
        SchedulerProvider schedulerProvider=SchedulerProvider.DEFAULT;
        TestPresenter testPresenter=new TestPresenter(mAbsService,schedulerProvider);

需要把TestPresenter需要的參數(shù)一個(gè)個(gè)的實(shí)例化偏螺,然后作為參數(shù)傳給它行疏。試想一下,如果我們的AbsService和SchedulerProvider 還需要很多參數(shù)套像,或者TestPresenter需要3個(gè)乃至更多的參數(shù)酿联,那我們實(shí)例化一個(gè)TestPresenter要做的操作是不是太多了,這樣實(shí)在是太夸張了,我們只是需要一個(gè)TestPresenter實(shí)例而已贞让,就必須知道TestPresenter的Dependency是什么周崭,TestPresenter的Dependency的Dependency是什么。喳张。续镇。首先這樣做操作很是繁瑣,其次销部,這樣做摸航,導(dǎo)致代碼耦合程度非常高,我們改變其中一環(huán)的時(shí)候舅桩,就要做大量的代碼改動(dòng)酱虎。
然而,如果我們使用dagger2江咳,這些問(wèn)題就可以迎刃而解了逢净。dagger2用一個(gè)類似依賴工廠的東西,將所需的依賴統(tǒng)一管理起來(lái)歼指,所有需要用到依賴的類都可以到這里尋找相應(yīng)的依賴爹土,并且dagger2會(huì)自動(dòng)搜索這個(gè)類所用到的依賴的依賴,系統(tǒng)會(huì)自動(dòng)識(shí)別這個(gè)依賴關(guān)系踩身。

Dagger2的基本使用方法

Dagger2主要由2個(gè)部分組成:首先我們需要一個(gè)產(chǎn)生依賴的工廠Module胀茵,然后我們需要一個(gè)管理這些Module的管理員Component。
Module的實(shí)現(xiàn)(接前面的例子):

@Module
public class AppModule {

    @Provides
    public SchedulerProvider provideSchedulerProvider() {
        return SchedulerProvider.DEFAULT;
    }

    @Provides
    public AbsService provideApi() {
        return AbsService.getInstance();
    }

    @Provides
    public AbsService.AbsApi provideAbsApi() {
        return AbsService.getService();
    }

    @Provides
    public TestPresenter providePresenter(AbsService absService,SchedulerProvider schedulerProvider) {
        return new TestPresenter(absService,schedulerProvider);
    }
}

在上面的Module類的中挟阻,我們用@Module注解標(biāo)注了這個(gè)類琼娘,告訴dagger2這個(gè)類是提供依賴的Module,下面很多個(gè)用@Provides注解標(biāo)注的方法則是告訴dagger2這個(gè)方法用來(lái)提供依賴。如果需要提供單例的依賴則需要在前面附鸽,加上@Singleton注解脱拼。這個(gè)時(shí)候,可能有人會(huì)有疑問(wèn)了坷备,多層的依賴dagger是怎么找的熄浓?dagger2尋找依賴的規(guī)則如下:
步驟1:首先查找@Module標(biāo)注的類中是否存在提供依賴的方法。
步驟2:若存在提供依賴的方法省撑,查看該方法是否存在參數(shù)赌蔑。
a:若存在參數(shù),則按從步驟1開始依次初始化每個(gè)參數(shù)竟秫;
b:若不存在娃惯,則直接初始化該類實(shí)例,完成一次依賴注入肥败。
步驟3:若不存在提供依賴的方法趾浅,則查找@Inject標(biāo)注的構(gòu)造函數(shù)愕提,看構(gòu)造函數(shù)是否存在參數(shù)。
a:若存在參數(shù)潮孽,則從步驟1開始依次初始化每一個(gè)參數(shù)
b:若不存在揪荣,則直接初始化該類實(shí)例筷黔,完成一次依賴注入往史。
通過(guò)這樣一個(gè)操作,dagger2就能直接自動(dòng)的尋找所需的依賴了佛舱。

Component的實(shí)現(xiàn):

@Component(modules = {AppModule.class})
public interface AppComponent {
    TestPresenter testPresenter();
}

或是

@Component(
        modules = AppModule.class
)
public interface AppComponent {
    TestActivityFragment2 inject(TestActivityFragment2 activity);
}

Component需要用 @Component修飾一下椎例,來(lái)標(biāo)注這是一個(gè)dagger2的Component,而不是一個(gè)普通的interface请祖,用modules = AppModule.class來(lái)告訴dagger2要從哪個(gè)Module中去找依賴订歪,注意如果有多個(gè)Module,可以和第一種方法一樣寫成數(shù)組的形式肆捕。
在Component中的方法是我們需要使用依賴的時(shí)候使用的刷晋,比如第一種,就比較直觀慎陵,我們需要TestPresenter 這個(gè)實(shí)例眼虱,直接定義這個(gè)方法,dagger2就會(huì)自動(dòng)生成一個(gè)Dagger+Component名字(如DaggerAppComponent )這樣一個(gè)方法席纽,這個(gè)方法就從AppComponent管理的AppModule中尋找依賴捏悬,返回一個(gè)Presenter的實(shí)例。
然后在需要調(diào)用實(shí)例的時(shí)候只需要像下面這樣做就可以完成實(shí)例化了:

public class TestActivityFragment2 extends Fragment {
    private TestPresenter mTestPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        AppComponent appComponent =    DaggerAppComponent.builder().appModule(new AppModule(this)).build();  
        mTestPresenter= appComponent.testPresenter();   
    }
}

對(duì)于第二種方式润梯,我們需要這樣調(diào)用:

public class TestActivityFragment2 extends Fragment {
     @Inject
      TestPresenter mTestPresenter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        AppComponent appComponent =  DaggerAppComponent.builder().appModule(new AppModule(this)).build();  
        appComponent.inject(this); 
    }
}

DaggerAppComponent實(shí)現(xiàn)這個(gè)方法的方式是过牙,去TestActivityFragment2 里面所有被 @Inject修飾的變量,然后調(diào)用 AppModule相應(yīng)的Provider方法對(duì)相應(yīng)類型提供依賴纺铭。對(duì)于這兩種方法寇钉,一般來(lái)說(shuō)我會(huì)選擇第二種,寫起來(lái)比較簡(jiǎn)便舶赔。

參考:http://www.reibang.com/p/4270b8e86d2f

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末扫倡,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子顿痪,更是在濱河造成了極大的恐慌镊辕,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,743評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚁袭,死亡現(xiàn)場(chǎng)離奇詭異征懈,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)揩悄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門卖哎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事亏娜』牢眩” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵维贺,是天一觀的道長(zhǎng)它掂。 經(jīng)常有香客問(wèn)我,道長(zhǎng)溯泣,這世上最難降的妖魔是什么虐秋? 我笑而不...
    開封第一講書人閱讀 56,485評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮垃沦,結(jié)果婚禮上客给,老公的妹妹穿的比我還像新娘。我一直安慰自己肢簿,他們只是感情好靶剑,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著池充,像睡著了一般桩引。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上纵菌,一...
    開封第一講書人閱讀 49,821評(píng)論 1 290
  • 那天阐污,我揣著相機(jī)與錄音,去河邊找鬼咱圆。 笑死笛辟,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的序苏。 我是一名探鬼主播手幢,決...
    沈念sama閱讀 38,960評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼忱详!你這毒婦竟也來(lái)了围来?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,719評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤匈睁,失蹤者是張志新(化名)和其女友劉穎监透,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體航唆,經(jīng)...
    沈念sama閱讀 44,186評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胀蛮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了糯钙。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粪狼。...
    茶點(diǎn)故事閱讀 38,650評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡退腥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出再榄,到底是詐尸還是另有隱情狡刘,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布困鸥,位于F島的核電站嗅蔬,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏窝革。R本人自食惡果不足惜购城,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望虐译。 院中可真熱鬧,春花似錦吴趴、人聲如沸漆诽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)厢拭。三九已至,卻和暖如春撇叁,著一層夾襖步出監(jiān)牢的瞬間供鸠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工陨闹, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留楞捂,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,370評(píng)論 2 360
  • 正文 我出身青樓趋厉,卻偏偏與公主長(zhǎng)得像寨闹,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子君账,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容

  • Dagger2 入門 2016-12-21 更新:添加@Subcomponent注解以及Lazy與Provider...
    fxzou閱讀 28,550評(píng)論 77 331
  • 本文的分析基于dagger2的2.7版本繁堡。 谷歌開發(fā)維護(hù)的Dagger2出來(lái)有很長(zhǎng)時(shí)間了,目前在很多開源項(xiàng)目上也能...
    sososeen09閱讀 13,593評(píng)論 31 108
  • 什么的依賴注入 在軟件工程中乡数,依賴注入是實(shí)現(xiàn)控制反轉(zhuǎn)的方式之一椭蹄。百度百科中對(duì)于控制反轉(zhuǎn)的解釋如下:控制反轉(zhuǎn)(Inv...
    小甜李子閱讀 1,672評(píng)論 5 3
  • 函數(shù) function 函數(shù)也是一個(gè)對(duì)象 函數(shù)中可以封裝一些功能(代碼),在需要時(shí)可以執(zhí)行這些功能(代碼) 函數(shù)中...
    hi武林高手閱讀 187評(píng)論 0 3
  • 來(lái)到這座的陌生的城市净赴,空氣中似乎彌漫她的氣息绳矩,讓我淪陷,突然想見(jiàn)見(jiàn)你劫侧,看看你最近改變埋酬,qq上那個(gè)地址熟記于心...
    折兒貓閱讀 196評(píng)論 0 0