前言
上文dagger2入門教程以一個實例介紹了dagger2的相關組件,概念和使用的方法。本文繼續以上文的例子爲基礎,對其進行源碼分析。
1、 dagger2生成的代碼
如下圖所示,右邊是我們申明的Component和Module,左邊是dagger2生成的代碼。從圖中可以看出,我們申明瞭ActivityComponent,dagger2就會給我們生成對應的Dagger2ActivityComponent。其他的類都是dagge2內部用來負責依賴注入的工廠類。
我們再看看dagger2內部的工廠類之間的關係
- Component:Ioc控制器,通過inject傳入對象,對對象屬性進行賦值
- Provider:對象生成器,每一個類型的對象對應一個Provider。Provider依賴客戶端傳入的Module或者Dependency Component來實際的構造對象。
- MemberInjector:給對象屬性的賦值,每有一個對象有屬性需要注入,那麼就存在一個MemberInjector,MemberInjector依賴Provider來生成對象。
2、源碼分析
2.1 Component的生成過程
(1) Component依賴的構造
上圖是我們申明的FragmentComponent,下圖是Dagger2生成的Dagger2FragmentComponent。
可以看出FragmentComponent每申明一個modules和dependencies,在Dagger2FragmentComponent就有一個對應的屬性,這些屬性需要我們在構造Dagger2FragmentComponent手動的傳進去
再看看我們是怎麼傳進去的
(2)Component Provider的構造
從下圖中可以看出Dagger2Component需要注入4個對象,包括3個類型的對象(ActivityObj,ActivityScopeObj,FragmentObj),有2個類需要被注入(Dagger2Fragment,FragmentObj,因爲他們存在@Inject修飾的屬性)
與之對象的在生成的Dagger2FragmentComponent中就存在3個Provider(一種類型的對象對應一個),還有2個MemberInjector,Provider負責生成對象,MemberInjector負責去給被注入的對象屬性賦值。
雖然Dagger2ActivityComponent裏面存在Provider< ActivityObjProvider>,但是Provider< ActivityObjProvider>是私有屬性,FragmentComponent無法利用它來生成ActivityObj的對象。因此ActivityComponent可以通過在申明的時候暴接口來提供對外提供對象的能力(eg:ActivityComponent.activityObj),在Dagger2ActivityComponent裏面activityObj的實現,實際也是通過Provider< ActivityObjProvider>來生成對象。
注意:Dagger2裏面都是按照返回值的類型進行對象匹配,與方法名無關
2.2 Provider的生成過程
2.2.1 非Scope修飾的情況
2.2.2 Scope修飾的情況
相比較於非Scope修飾的情況,provideActivityScopeProvider用ScopeProvider裹了一層,在ScopeProvider裏面,用一次變量result來保存了ActivityModule.provideActivityScopeOb返回的值,只有第一次調用的時候,纔會通過ActivityModule.provideActivityScopeOb去生成ActivityScopeObj對象,後續直接用result來返回。
因此,可以得出結論:只要是Scope修飾的方法,在同一個Component裏面總返回一份單例
- 理論上來說:Component和其被注入對象的生命週期相同,比如說AppComponent其存在的生命週期=App的生命週期,ActivityComponent的生命週期=Activity的生命週期
我們不要被Scope的名稱所迷惑了,比如說,ActivityScope,SingleInstance,AppScope等。他們的本質都是相同的,只要用Scope修飾了返回的方法,他們在同一個Component內返回一個單例。唯一用於區分他們大小的就是Component之間的依賴關係。比如說AppScope之所以比ActivityScope大,是因爲AppScope修飾了AppComponent,ActivityScope修飾了ActivityComponent,同時ActivityComponent依賴於AppComponent。因此AppScope>ActivityScope。