- 該系列部落格的最終目標: 搭建 MVP + Dagger2 框架
- 該系列部落格包含以下幾篇內容:
- Dagger 2 系列(一) -- 前奏篇:依賴注入的基本介紹
- Dagger 2 系列(二) -- 基礎篇:@Inject、@Component
- Dagger 2 系列(三) -- 基礎篇:@Module 和@Provides
- Dagger 2 系列(四) -- 基礎篇:@Named 和 @Qualifier
- Dagger 2 系列(五) -- 進階篇:@Scope 和 @Singleton
在這篇文章中你會看到什麼:
@Inject
是什麼@Component
是什麼@Inject
和@Component
如何協同作戰。
1. 前提
在介紹他們之前我們來看一段我們在專案中看到的類似的程式碼:
public class ClassA{
ClassB classB = new ClassB();
ClassC classC = new ClassC("xxx",xxx);
.....
}
複製程式碼
如你所見,當我們在目標類初始化其他類時,這些工作幾乎都是重複性的操作,我們可不可以用一種方案來替代這種操作,這時我們所使用的 Dagger2
的成員 @Inject
和 @Component
就跳出來了,大聲喊道:我可以~~~
2. @Inject 是什麼?
@Inject
為了實現以上功能,我們需要完成以下步驟:
- 需要用註解
@Inject (Annotation)
來標註目標類中依賴類的例項物件 - 同樣用註解
@Inject (Annotation)
來標註所依賴的其他類的建構函式
。
目標類 ClassA
public class ClassA{
@Inject
ClassB classB;// 使用 @Inject 標註依賴類的例項物件
@Inject
ClassC classC;
}
複製程式碼
依賴類 ClassB
public class ClassB{
@Inject // 使用 @Inject 標註依賴類的建構函式
public ClassB(){}
....
}
複製程式碼
依賴類 ClassC
public class ClassC{
@Inject
public ClassC(XXX xxx, XXX xxx){
...
}
}
複製程式碼
注意:在使用 @Inject 標註類的建構函式,只能標註一個建構函式,無法標註多個。
雖然 目標類 和 依賴類 都使用了@Inject
來標記,但是他們並沒有產生實在意義上的聯絡,這時 @Component
就充當了媒婆的角色。
3. @Component 是什麼
作用:將Module中產生的依賴物件自動注入到需要依賴例項的Container中
很明顯 @Component
是一個註解,那麼被 @Component
標記的類理所當然的被稱為 註解類,並且該類必須是介面或抽象類。那麼下面我們看一下這個媒婆是怎麼開展工作的:
1.@Component
標註類的例項必須存在目標類中
2.Component
會查詢目標類中用 @Inject
註解標註的屬性
3. 查詢到相應的屬性後,會接著查詢該屬性對應的用 @Inject
標註的建構函式(這時候就發生聯絡了)
4. 剩下的工作就是初始化該屬性的例項並把例項進行賦值
具體過程如下圖:
4. 簡單使用
- 依賴類 -- User ,使用
@Inject
標註建構函式
public class User {
private String mName = "jack chen";
private int mAge = 40;
@Inject
public User() { }
public String getName() {
return mName;
}
public void setName(String mName) {
this.mName = mName;
}
public int getAge() {
return mAge;
}
public void setAge(int mAge) {
this.mAge = mAge;
}
}
複製程式碼
- 媒介類 -- UserComponentm ( 介面), 使用
@Component
註解該類
@Component
public interface UserComponent {
void inject(MainActivity mMainActivity);
}
複製程式碼
- 目標類 -- MainActivity,使用
@Inject
註解相關例項變數
public class MainActivity extends AppCompatActivity {
@Inject
User mUser;
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 這一句程式碼是完成依賴注入的關鍵
DaggerUserComponent.builder().build().inject(this);
Log.e(TAG,"name : " + mUser.getName() + " age :" + mUser.getAge());
mUser.setAge(50);
mUser.setName("blur");
Log.e(TAG,"name2 : " + mUser.getName() + " age2 :" + mUser.getAge());
}
}
複製程式碼
- 執行結果
name : jack chen age :40
name2 : blur age2 :50
複製程式碼
5. 總結
到此為止,我們已經實現了基本的基於 Dagger2
的依賴注入。下面我們把過程再梳理一遍:
- 用
@Inject
註解標註目標類中依賴類的例項物件 - 用
@Inject
註解標註依賴類的建構函式 - 若其他類還依賴於其他的類,則重複進行上面2個步驟
- 呼叫
Component
(注入器)的injectXXX
(Object)方法開始注入(injectXXX
方法名字是官方推薦的名字,以inject開始)
Component
就像 目標類
和自己的 依賴類
的媒介,把目標類依賴的例項注入到目標類中,來初始化目標類中的依賴例項變數。