前言
dagger2貌似從兩年前開始在各大android論壇刷屏巩检,一堆Retrofit+RxJava+Dagger2項目如雨后春筍一樣冒了出來悴务。不過當時并沒有趕這個潮流俭正,主要是因為手頭上項目已經(jīng)較為龐大性昭,而引入dagger2這種入門門檻比較高的庫到項目里收益并不好估計撇眯,當然更明顯的原因就是懶咯涤躲。
那現(xiàn)在為啥要用dagger2呢棺耍?因為新公司有一套插件框架,在插件中引入dagger2的成本相對小了不少种樱,可以實驗性的去嘗試下蒙袍,但是最終還是決定不在項目中引入dagger2,原因最后一篇文章會說到嫩挤。
什么是dagger2
關于dagger2的來龍去脈網(wǎng)上的文章說的足夠多了害幅,也就不多說了,只提下我覺得重要的幾點
- 編譯期的依賴注入框架
- 使用代碼生成而不用反射
以上兩點決定了dagger2的注入只限于編譯期可以確定的靜態(tài)注入岂昭,像View以现,Activity這種運行時產(chǎn)生,且實例是由android框架創(chuàng)建出來的對象只能作為被注入的組件,而無法做為依賴注入到其他地方。當然有舍有得
- dagger2擁有更強的運行時性能
- 較為完善的編譯期代碼檢查
- 因為在編譯期就生成了全部代碼邑遏,所以調(diào)試也沒什么問題佣赖,不過個人覺得生成的代碼不夠直觀,調(diào)試起來還是很麻煩
依賴注入框架解決的問題
先說說我理解的依賴
依賴是指某個模塊A要實現(xiàn)某個功能需要其他模塊B无宿。
最原始也最簡單的的方式是在模塊內(nèi)new一個B的對象出來茵汰,這樣會造成B的構造函數(shù)修改,需要修改A中的代碼孽鸡,兩者耦合度非常高蹂午。
依賴注入
依賴注入是不在A中去創(chuàng)建 B的實例,而是讓上層調(diào)用者注入一個B的對象彬碱,這樣可以讓模塊A不再因為B的構造方法的修改而改變
注意一點豆胸,依賴注入只讓A擺脫了和B的構造函數(shù)的耦合,至于A中對B的依賴基于一個實現(xiàn)還是一個接口巷疼,依賴注入是管不著的(依賴注入和面向接口編程都是為了模塊間解耦但是沒有直接的關系)
如果A依賴于一個接口晚胡,而這個接口的實現(xiàn)B又是從外部傳入的,這樣可以讓A完全獨立于B而存在嚼沿,復用起來就更為簡單
依賴注入帶來的問題
所有的下層模塊將創(chuàng)建依賴的任務都往上拋估盘,那么必然會導致最上層的模塊需要創(chuàng)建所有必須的依賴,而到依賴的傳遞過程也會多很多setter或者增加很多構造參數(shù)
//網(wǎng)上找的一個比較合適的例子
public class LoginActivity extends AppCompatActivity {
LoginActivityPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OkHttpClient okHttpClient = new OkHttpClient();
RestAdapter.Builder builder = new RestAdapter.Builder();
builder.setClient(new OkClient(okHttpClient));
RestAdapter restAdapter = builder.build();
ApiService apiService = restAdapter.create(ApiService.class);
UserManager userManager = UserManager.getInstance(apiService);
UserDataStore userDataStore = UserDataStore.getInstance(
getSharedPreferences("prefs", MODE_PRIVATE)
);
//Activity只需要依賴LoginActivityPresenter
//但因為使用了依賴注入骡尽,讓下層模塊相互解耦遣妥,導致activity需要承擔所有依賴的創(chuàng)建任務
//也就多了上面那么多代碼
presenter = new LoginActivityPresenter(this, userManager, userDataStore);
}
}
依賴注入框架的意義
依賴注入框架的目的就在于承擔了最上層創(chuàng)建依賴的職責,并且利用注解在合適的地方注入依賴攀细,簡化依賴的創(chuàng)建和傳遞的模板代碼
public class LoginActivity extends AppCompatActivity {
@Inject
LoginActivityPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Satisfy all dependencies requested by @Inject annotation
getDependenciesGraph().inject(this);
}
}
當然簡化掉的代碼沒那么夸張箫踩,創(chuàng)建依賴的方法只不過是從activity中移到了依賴注入框架中,而依賴注入框架和業(yè)務代碼之間是沒有耦合的谭贪,可以按照一定的規(guī)則進行復用
dagger2的基本概念
依賴的提供方
dagger2中有兩種提供依賴的方式
- 使用@Inject注解構造器的類
- 使用在自己可以修改源碼的類中
- 使用@Module注解包含提供依賴方法的類境钟,使用@Provide方法主角提供依賴的方法
- 用在提供沒有修改源碼權限的類的依賴
依賴的需求方
其實也可以分為兩類
- 正常的類,使用了@Inject注解了成員變量的類
- 這里注入依賴需要自己觸發(fā)
- @Inject注解構造器的類
- 這里@Inject注解的成員變量和構造器參數(shù)都會去框架中去找俭识,這個過程是編譯時自動完成的
- 這些類既是依賴的需求方也是依賴的提供方
依賴注入器
使用@Component或者@SubComponent注解的接口或者抽象類
- 描述可以提供哪些依賴
- 描述可以注入到哪些依賴需求方
- 管理依賴的生命周期
也許看完上面一堆你還是一頭霧水慨削,那么后面就通過代碼循序漸進來熟悉dagger2吧
相關文章
dagger2從入門到放棄-概念
dagger2從入門到放棄-最基礎的用法介紹
dagger2從入門到放棄-Component的繼承體系、局部單例
dagger2從入門到放棄-ActivityMultibindings
dagger2從入門到放棄-dagger.android
dagger2從入門到放棄-其他用法
dagger2從入門到放棄-多模塊項目下dagger的使用
dagger2從入門到放棄-為何放棄