Dagger2是一個Java和Android的依賴注入框架.
本文介紹Android中dagger2的基本使用.
其中包括@Inject, @Component, @Module和@Provides註解的使用.
使用依賴注入的好處
1.使用類和被依賴的對象構造分開,這樣如果我們需要改變被依賴類的構造方法,不必改動每一個使用類.
2.對各種被依賴類的實例,可以只構造一次.
3.當我們需要更換一種實現時,只需要保證接口一致.
4.利於單元測試,我們可以方便地mock依賴類的對象.
優點總結: 創建對象和使用對象分離, 模塊化增強.
註解說明:
@Inject: 通常在需要依賴的地方使用這個註解。換句話說,你用它告訴Dagger這個類或者字段需要依賴注入。這樣,Dagger就會構造一個這個類的實例並滿足他們的依賴。
@Module: Modules類裏面的方法專門提供依賴,所以我們定義一個類,用@Module註解,這樣Dagger在構造類的實例的時候,就知道從哪裏去找到需要的 依賴。modules的一個重要特徵是它們設計爲分區並組合在一起(比如說,在我們的app中可以有多個組成在一起的modules)。
@Provide: 在modules中,我們定義的方法是用這個註解,以此來告訴Dagger我們想要構造對象並提供這些依賴。
@Component: Components從根本上來說就是一個注入器,也可以說是@Inject和@Module的橋樑,它的主要作用就是連接這兩個部分。 Components可以提供所有定義了的類型的實例,比如:我們必須用@Component註解一個接口然後列出所有的@Modules組成該組件,如 果缺失了任何一塊都會在編譯的時候報錯。所有的組件都可以通過它的modules知道依賴的範圍。
@Scope: Scopes可是非常的有用,Dagger2可以通過自定義註解限定註解作用域。後面會演示一個例子,這是一個非常強大的特點,因爲就如前面說的一樣,沒 必要讓每個對象都去了解如何管理他們的實例。在scope的例子中,我們用自定義的@PerActivity註解一個類,所以這個對象存活時間就和 activity的一樣。簡單來說就是我們可以定義所有範圍的粒度(@PerFragment, @PerUser, 等等)。
Qualifier: 當類的類型不足以鑑別一個依賴的時候,我們就可以使用這個註解標示。例如:在Android中,我們會需要不同類型的context,所以我們就可以定義 qualifier註解“@ForApplication”和“@ForActivity”,這樣當注入一個context的時候,我們就可以告訴 Dagger我們想要哪種類型的context。
Dagger2 具體使用案例:
1.配置
在AppMode 下的build.gradle進行配置,然後同步就可以導入相關dagger2的包:
/***************************************使用dagger2需要的配置Start*****************************************/
apply plugin: 'com.neenbedankt.android-apt'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
/************使用dagger2需要的配置End************************/
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:26.0.0-alpha1'
/************dagger2使用需要的庫start***********************/
compile "com.google.dagger:dagger:2.9"
apt 'com.google.dagger:dagger-compiler:2.9'
//Dagger2中會用到@Generated註解,而AndroidSDK中沒有javax.anotation.Generated.class,所以在 Android 項目要添加此句
provided 'org.glassfish:javax.annotation:10.0-b28'
/***********dagger2使用需要的庫end*************************/
}
2.創建一個類Student用於測試Mode
/**
* Created by lixby on 2017/8/10.
*/
public class Student {
private String sName;
private String sSex;
private String sAge;
public Student(String sName, String sSex, String sAge) {
this.sName = sName;
this.sSex = sSex;
this.sAge = sAge;
}
public String getsAge() {
return sAge;
}
public void setsAge(String sAge) {
this.sAge = sAge;
}
public String getsName() {
return sName;
}
public void setsName(String sName) {
this.sName = sName;
}
public String getsSex() {
return sSex;
}
public void setsSex(String sSex) {
this.sSex = sSex;
}
public void showStudentInfo(){
Log.i("lixby","student Name:"+sName);
Log.i("lixby","student sSex:"+sSex);
Log.i("lixby","student sAge:"+sAge);
}
}
3.創建StudentModule,用於體提供Student實例給其他地方使用,代碼很簡單,一定要注意提供@Module 和@Provides 註解,要不無法沒被Dagger2識別:
/**
* Created by lixby on 2017/8/10.
*/
@Module
public class StudentModule {
@Provides
public Student provideStudent(){
return new Student("小明","男","18");
}
}
4.創建AppComPonent
/**
* Created by lixby on 2017/8/10.
*/
@Singleton
@Component(modules = {ApplicationModule.class,StudentModule.class})
public interface AppComPonent {
//MainActivity 目標類
void inject(MainActivity mainActivity);
}
Component是注入器,它一端連接目標類,另一端連接目標類依賴實例,它把目標類依賴實例注入到目標類中。上面的Module是一個提供類實例的類,所以Module應該是屬於Component的實例端的(連接各種目標類依賴實例的端),Component的新職責就是管理好Module,Component中的modules屬性可以把Module加入Component,modules可以加入多個Module。
第三和第四中,Module中的創建類實例方法用Provides進行標註,Component在搜索到目標類中用Inject註解標註的屬性後,Component就會去Module中去查找用Provides標註的對應的創建類實例方法。
5.按照上面步驟完成Module和Component的創建,然後執行Rebuild Project就會自動生成對應的關聯文件。
6.初始化AppComPonent
/**
* Created by lixby on 2017/8/10.
*/
public class MyApplication extends Application{
static AppComPonent mAppComPonent;
@Override
public void onCreate() {
super.onCreate();
inItDaggerModule();
}
private void inItDaggerModule(){
mAppComPonent= DaggerAppComPonent.builder()
.applicationModule(new ApplicationModule(this))
.studentModule(new StudentModule())
.build();
}
public static AppComPonent getComponent() {
return mAppComPonent;
}
}
7.在MainActivity中通過@Inject 將Student注入,就可以使用Student 實例了:
public class MainActivity extends AppCompatActivity {
@Inject
Student mStudent;
@Override
protected void onCreate(Bundle savedInstanceState) {
MyApplication.getComponent().inject(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mStudent.showStudentInfo();
}
}
總結:
Inject,Component,Module,Provides是dagger2中的最基礎最核心的知識點。奠定了dagger2的整個依賴注入框架。
Inject主要是用來標註目標類的依賴和依賴的構造函數
Component它是一個橋樑,一端是目標類,另一端是目標類所依賴類的實例,它也是注入器(Injector)負責把目標類所依賴類的實例注入到目標類中,同時它也管理Module。
Module和Provides是爲解決第三方類庫而生的,Module是一個簡單工廠模式,Module可以包含創建類實例的方法,這些方法用Provides來標註
這個Demo很簡單,只是初識,還需要進一步在實踐中去使用和總結。