Dagger2 源碼簡(jiǎn)析

Dagger2是首個(gè)使用生成代碼實(shí)現(xiàn)完整依賴(lài)注入的框架,極大減少了使用者的編碼負(fù)擔(dān)。
我們?nèi)タ纯碊agger2 是如何為我們注入對(duì)象的。

假設(shè)我們需要在MainActivity中注入對(duì)象DataManager:

public class MainActivity extends AppCompatActivity {

    @Inject
    DataManager dataManager;

}

使用@Inject標(biāo)志被注入的對(duì)象dataManager(注意dataManager不能為private)

Dagger2中浮还,負(fù)責(zé)提供依賴(lài)的組件被稱(chēng)為Module。
創(chuàng)建Module類(lèi)闽巩,如下:

@Module
public class AppModule {


    /**
     * 帶@Provides 注解 ,說(shuō)明該方法是提供依賴(lài)
     * @return
     */
    @Provides
    public DataManager provideManager() {
        return new DataManager();
    }

}

使用@Module注解來(lái)標(biāo)識(shí)類(lèi)型為module担汤,并用@Provides標(biāo)識(shí)提供依賴(lài)的方法涎跨。

Dagger2中,我們需要Component 來(lái)連接 Module 和 @Inject 來(lái)完成對(duì)象的注入:
創(chuàng)建 Component接口:


@Component(modules = {AppModule.class})
@Singleton
public interface AppComponent {

    void inject(MainActivity activity);
}

使用@Component注解來(lái)標(biāo)識(shí)類(lèi)型為Component崭歧,參數(shù)modules 可以依賴(lài)多個(gè)module隅很。
接口中的inject方法需要該注入對(duì)象所在的類(lèi)作為參數(shù)。注意:這里必須是注入對(duì)象所在的類(lèi)MainActivity率碾,而不可以寫(xiě)成其父類(lèi)叔营。

編譯。

Dagger2 會(huì)生成一些輔助類(lèi)所宰。

帶@Component注解 :生成 Dagger_(帶@Component注解接口名稱(chēng))绒尊。這里是AppComponent。因此會(huì)生成 Dagger_AppComponent仔粥;

帶@Module 注解 :生成 (帶@Mudule類(lèi)名)_(帶@Provides注解的方法名)Factory婴谱。這里是 AppModule_ProvideManagerFactory

帶@Inject 注解:生成 (需要注入對(duì)象所在的類(lèi)名)_MembersInjector。
這里是MainActivity_MembersInjector躯泰。

類(lèi)圖:

03.png

在MainActivity中會(huì)調(diào)用以下代碼:


 DaggerAppComponent
                .builder()
                .appModule(new AppModule())
                .build()
                .inject(this);

去看看DaggerAppComponent源碼:

05.png
  1. 調(diào)用build方法創(chuàng)建出DaggerAppComponent實(shí)例谭羔。
  2. 在創(chuàng)建DaggerAppComponent實(shí)例時(shí),調(diào)用了initialize(builder)麦向,創(chuàng)建AppModule_ProvideManagerFactory 和MainActivity_MembersInjector 實(shí)例瘟裸,調(diào)用了相對(duì)應(yīng)create的方法。

MainActivity_MembersInjector 源碼:

06.png
  1. 調(diào)用create的方法創(chuàng)建實(shí)例時(shí) 傳入了 AppModule_ProvideManagerFactory 作為參數(shù)诵竭。

  2. 但 .inject(this)方法時(shí)话告,調(diào)用了injectMembers方法兼搏,看到這個(gè)方法,可以知道為什么datamanage 不能為private和為什么調(diào)用inject方法傳參數(shù)時(shí)不能寫(xiě)父類(lèi)了超棺。

  3. dataManage 實(shí)例的創(chuàng)建調(diào)用了AppModule_ProvideManagerFactory的get方法向族。

看看AppModule_ProvideManagerFactory的源碼:

04.png

可以看到,get方法其實(shí)調(diào)用了AppModule 的provideManager方法棠绘,而這個(gè)方法new DataManager()件相;完成對(duì)象的注入。

這就是Dagger2 為我們注入對(duì)象處理的流程氧苍。

我們?cè)贛ainActivity 再注入一個(gè)對(duì)象Person夜矗,看看Dagger2 生成了怎么樣的輔助類(lèi)。

修改如下:
MainActivity :


public class MainActivity extends AppCompatActivity {

    @Inject
    DataManager dataManager;

    @Inject
    Person person;
}

修改AppModule:


@Module
public class AppModule {


    /**
     * 帶@Provides 注解 让虐,說(shuō)明該方法是提供依賴(lài)
     * @return
     */
    @Provides
    public DataManager provideManager() {
        return new DataManager();
    }


    @Provides
    public Person providePerson(){
        return new Person();
    }


}

類(lèi)圖:

08.png

如果是多層依賴(lài) 又會(huì)生成什么輔助類(lèi)紊撕?

添加 UserModule :


@Module
public class UserModule {


    @Provides
    public User provideUser(){
        return new User();
    }
}

修改AppComponent


@Component(modules = {AppModule.class,UserModule.class})
@Singleton
public interface AppComponent {

    void inject(MainActivity activity);
}

修改MainActivity


public class MainActivity extends AppCompatActivity {


    @Inject
    DataManager dataManager;


    @Inject
    Person person;


    @Inject
    User user;

}

類(lèi)圖:

09.png

可以看出

  1. Component 只是 Module 和 Inject 中間的橋梁
  2. Module 相當(dāng)于簡(jiǎn)單工廠,提供了各種依賴(lài)

輔助類(lèi)的生成規(guī)則:

帶@Component注解 :生成 Dagger_(帶@Component注解接口名稱(chēng))。這里是AppComponent赡突。因此會(huì)生成 Dagger_AppComponent对扶;

帶@Module 注解 :生成 (帶@Mudule類(lèi)名)_(帶@Provides注解的方法名)Factory。這里是 AppModule_ProvideManagerFactory

帶@Inject 注解:生成 (需要注入對(duì)象所在的類(lèi)名)_MembersInjector惭缰。
這里是MainActivity_MembersInjector浪南。

END。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末漱受,一起剝皮案震驚了整個(gè)濱河市络凿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌昂羡,老刑警劉巖絮记,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異虐先,居然都是意外死亡怨愤,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)赴穗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)憔四,“玉大人,你說(shuō)我怎么就攤上這事般眉×苏裕” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵甸赃,是天一觀的道長(zhǎng)柿汛。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么络断? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任裁替,我火速辦了婚禮,結(jié)果婚禮上貌笨,老公的妹妹穿的比我還像新娘弱判。我一直安慰自己,他們只是感情好锥惋,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布昌腰。 她就那樣靜靜地躺著,像睡著了一般膀跌。 火紅的嫁衣襯著肌膚如雪遭商。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,036評(píng)論 1 285
  • 那天捅伤,我揣著相機(jī)與錄音劫流,去河邊找鬼。 笑死丛忆,一個(gè)胖子當(dāng)著我的面吹牛祠汇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播熄诡,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼座哩,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了粮彤?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤姜骡,失蹤者是張志新(化名)和其女友劉穎导坟,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體圈澈,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡惫周,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了康栈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片递递。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖啥么,靈堂內(nèi)的尸體忽然破棺而出登舞,到底是詐尸還是另有隱情,我是刑警寧澤悬荣,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布菠秒,位于F島的核電站,受9級(jí)特大地震影響氯迂,放射性物質(zhì)發(fā)生泄漏践叠。R本人自食惡果不足惜言缤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望禁灼。 院中可真熱鬧管挟,春花似錦、人聲如沸弄捕。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)察藐。三九已至皮璧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間分飞,已是汗流浹背悴务。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留譬猫,地道東北人讯檐。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像染服,于是被迫代替她去往敵國(guó)和親别洪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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