前言
使用Dagger2前你必須了解的一些設(shè)計原則
Dagger2 最清晰的使用教程
請先看以上兩篇文章
dagger2 的大名我想大家都已經(jīng)很熟了,它是解決Android或java中依賴注入的一個類庫(DI類庫)唧喉。當(dāng)我看到一些開源的項目在使用dagger2時忍抽,我也有種匆匆欲動的感覺鸠项,因此就立馬想一探它的究竟,到底能給我?guī)碓鯓拥暮锰幯北睢T趯W(xué)習(xí)使用dagger2的過程中浅辙,我遇到了以下的一些困惑:
- dagger2中的Inject,Component,Module,Provides等等都是什么東東阎姥,有什么作用?
- dagger2到底能帶來哪些好處呼巴?
- 怎樣把dagger2應(yīng)用到具體項目中?
在具體學(xué)習(xí)dagger2的時候诊赊,看了好多博客碧磅,看的時候感覺挺簡單的遵馆,但是在真正使用到項目中時候货邓,腦袋就懵了,無從下手职辨,Component應(yīng)該怎么用拨匆,能放些什么方法? Module應(yīng)該放些啥內(nèi)容?Scope怎么起到作用域控制?.....各種疑問就橫空而出台腥。所以也許會有正在學(xué)習(xí)或即將要使用dagger2的同學(xué)在使用過程中遇到和我一樣的困惑绒北,因此我決定把我對dagger2的理解闷游、使用經(jīng)驗分享給大家,希望能對大家有幫助休吠。我會分幾節(jié)給講解dagger2瘤礁。
本節(jié)內(nèi)容
Inject梅尤,Component,Module赡盘,Provides 它們是什么缰揪?怎么去理解它們邀跃?各自有什么作用?主要從抽象的概念講解途戒,不會涉及到具體代碼的剖析喷斋。
提前科普知識點
在講解之前星爪,我希望大家對以下知識點有所了解(知道的同學(xué)可以跳過)
依賴注入設(shè)計模式
依賴注入(Dependency Injection簡稱DI)
java中注解(Annotation)
依賴注入:就是目標(biāo)類(目標(biāo)類需要進行依賴初始化的類,下面都會用目標(biāo)類一詞來指代)中所依賴的其他的類的初始化過程近零,不是通過手動編碼的方式創(chuàng)建久信,而是通過技術(shù)手段可以把其他的類的已經(jīng)初始化好的實例自動注入到目標(biāo)類中漓摩。
若您還是對依賴注入不了解,點擊我可以讓您了解更多dagger2就是實現(xiàn)依賴注入的一種技術(shù)手段管毙。
其次java注解的概念用法我們就不講了夭咬,dagger2中核心點就是java注解皱埠,點擊我可以了解更多java注解知識
正式開始
以下的內(nèi)容我會嘗試著去模仿dagger2的作者是怎樣一步步完成dagger2這樣偉大的依賴注入類庫的場景來講解(首先這個場景是我意淫的,大家勿噴训枢,模仿該場景主要目的是為了能由簡到難一步步更深入的了解dagger2)
Inject是什么鬼
先看一段代碼:
class A{
B b = new B();
C c = new C();
D d = new D(new E());
F f = new F(.....);
}
上面的代碼完全沒任何問題恒界,但是總感覺創(chuàng)建對象的這些代碼基本都是重復(fù)的體力勞動砚嘴,那何嘗不想個辦法十酣,把這些重復(fù)的體力勞動用一種自動化的、更省力的方法解決掉际长,這樣就可以讓開發(fā)的效率提高耸采,可以把精力集中在重要的業(yè)務(wù)上了。
我們可以用注解(Annotation)來標(biāo)注目標(biāo)類中所依賴的其他類工育,同樣用注解來標(biāo)注所依賴的其他類的構(gòu)造函數(shù)虾宇,那注解的名字就叫Inject
class A{ @Inject B b; } class B{ @Inject B(){ } }
這樣我們就可以讓目標(biāo)類中所依賴的其他類與其他類的構(gòu)造函數(shù)之間有了一種無形的聯(lián)系。但是要想使它們之間產(chǎn)生直接的關(guān)系如绸,還得需要一個橋梁來把它們之間連接起來嘱朽。那這個橋梁就是Component了。
Inject.png
Component又是什么鬼
Component也是一個注解類搪泳,一個類要想是Component稀轨,必須用Component注解來標(biāo)注該類,并且該類是接口或抽象類岸军。我們不討論具體類的代碼奋刽,我想從抽象概念的角度來討論Component。上文中提到Component在目標(biāo)類中所依賴的其他類與其他類的構(gòu)造函數(shù)之間可以起到一個橋梁的作用凛膏。
那我們看看這橋梁是怎么工作的:Component需要引用到目標(biāo)類的實例杨名,Component會查找目標(biāo)類中用Inject注解標(biāo)注的屬性,查找到相應(yīng)的屬性后會接著查找該屬性對應(yīng)的用Inject標(biāo)注的構(gòu)造函數(shù)(這時候就發(fā)生聯(lián)系了)猖毫,剩下的工作就是初始化該屬性的實例并把實例進行賦值。因此我們也可以給Component叫另外一個名字注入器(Injector)
component.png
小結(jié)下目標(biāo)類想要初始化自己依賴的其他類:
用Inject注解標(biāo)注目標(biāo)類中其他類
用Inject注解標(biāo)注其他類的構(gòu)造函數(shù)
若其他類還依賴于其他的類须喂,則重復(fù)進行上面2個步驟
調(diào)用Component(注入器)的injectXXX(Object)方法開始注入(injectXXX方法名字是官方推薦的名字,以inject開始)
Component現(xiàn)在是一個注入器吁断,就像注射器一樣,Component會把目標(biāo)類依賴的實例注入到目標(biāo)類中坞生,來初始化目標(biāo)類中的依賴仔役。
為啥又造出個Module
現(xiàn)在有個新問題:項目中使用到了第三方的類庫,第三方類庫又不能修改是己,所以根本不可能把Inject注解加入這些類中又兵,這時我們的Inject就失效了。
那我們可以封裝第三方的類庫卒废,封裝的代碼怎么管理呢沛厨,總不能讓這些封裝的代碼散落在項目中的任何地方,總得有個好的管理機制摔认,那Module就可以擔(dān)當(dāng)此任逆皮。可以把封裝第三方類庫的代碼放入Module中参袱,像下面的例子:
@Module public class ModuleClass{
//A是第三方類庫中的一個類
A provideA(){
return A();
}
}
Module 其實是一個簡單工廠模式电谣,Module里面的方法基本都是創(chuàng)建類實例的方法。接下來問題來了抹蚀,因為Component是注入器(Injector)剿牺,我們怎么能讓Component與Module有聯(lián)系呢?
Component的新職責(zé)
Component是注入器环壤,它一端連接目標(biāo)類晒来,另一端連接目標(biāo)類依賴實例,它把目標(biāo)類依賴實例注入到目標(biāo)類中镐捧。上文中的Module是一個提供類實例的類潜索,所以Module應(yīng)該是屬于Component的實例端的(連接各種目標(biāo)類依賴實例的端)臭增,Component的新職責(zé)就是管理好Module,Component中的modules屬性可以把Module加入Component竹习,modules可以加入多個Module誊抛。
那接下來的問題是怎么把Module中的各種創(chuàng)建類的實例方法與目標(biāo)類中的用Inject注解標(biāo)注的依賴產(chǎn)生關(guān)聯(lián),那Provides注解就該登場了整陌。
Provides最終解決第三方類庫依賴注入問題
Module中的創(chuàng)建類實例方法用Provides進行標(biāo)注拗窃,Component在搜索到目標(biāo)類中用Inject注解標(biāo)注的屬性后,Component就會去Module中去查找用Provides標(biāo)注的對應(yīng)的創(chuàng)建類實例方法泌辫,這樣就可以解決第三方類庫用dagger2實現(xiàn)依賴注入了随夸。
總結(jié)
Inject,Component震放,Module宾毒,Provides是dagger2中的最基礎(chǔ)最核心的知識點。奠定了dagger2的整個依賴注入框架殿遂。
Inject主要是用來標(biāo)注目標(biāo)類的依賴和依賴的構(gòu)造函數(shù)
Component它是一個橋梁诈铛,一端是目標(biāo)類,另一端是目標(biāo)類所依賴類的實例墨礁,它也是注入器(Injector)負責(zé)把目標(biāo)類所依賴類的實例注入到目標(biāo)類中幢竹,同時它也管理Module。
Module和Provides是為解決第三方類庫而生的恩静,Module是一個簡單工廠模式焕毫,Module可以包含創(chuàng)建類實例的方法,這些方法用Provides來標(biāo)注
component_module_inject.png
希望能幫您更好的理解dagger2驶乾。
dagger2——重點概念講解邑飒,融合篇(中)
原文地址
參考文章,更詳細
[Android]使用Dagger 2依賴注入 - DI介紹(翻譯)
[Android]使用Dagger 2依賴注入 - API(翻譯)
[Android]使用Dagger 2依賴注入 - 自定義Scope(翻譯)
[Android]使用Dagger 2依賴注入 - 圖表創(chuàng)建的性能(翻譯)
[Android]Dagger2Metrics - 測量DI圖表初始化的性能(翻譯)
[Android]使用Dagger 2進行依賴注入 - Producers(翻譯)
[Android]在Dagger 2中使用RxJava來進行異步注入(翻譯):