Dagger是干嘛的呢管嬉?
我的理解:一個依賴注入(DI)框架童本,使用范圍是java和android舔涎。
DI--dependence inject。
本文主要是記錄Android項目中获列,使用Dagger2的一個簡單的demo谷市。如果需要Dagger入門
的話,強(qiáng)烈推薦深入淺出Dagger2 : 從入門到愛不釋手系列击孩。
Dagger的優(yōu)點:
1.解耦迫悠。
2.簡化代碼。
Dagger注解
要使用Dagger首先必須了解相關(guān)的注解含義巩梢,下文主要介紹Dagger使用時创泄,最基本的的注解。
-
@Inject
javax.inject.Inject
翻譯過來就是“注入”的意思括蝠。
構(gòu)造函數(shù)注入:
public class Student {
private String name;
@Inject
public Student() {
this.name = "小美";
}
...
}
屬性注入:
@Inject
User user;
被注入的屬性不能用private修飾鞠抑。標(biāo)記user對象為目標(biāo)依賴類。
方法注入:
依賴需要this對象的時刻可以提供安全的this對象忌警。
@Module
dagger.Module
通常自定義的類碍拆,可通過其在其構(gòu)造函數(shù)上添加@Injcet注解,實現(xiàn)對象的自動創(chuàng)建慨蓝,但是第三方依賴感混,不能給其中類添加@Injcet。因此Module應(yīng)運而生礼烈。
Module其實是一個簡單工廠模式弧满,Module里面的方法基本都是創(chuàng)建類實例的方法。@Component
dagger.Component
Component是注入器此熬,它一端連接目標(biāo)類庭呜,另一端連接目標(biāo)類依賴實例,它把目標(biāo)類依賴實例注入到目標(biāo)類中犀忱。
@Component(modules = ActivityModule.class)
public interface MainComponent {
void inject(MainActivity activity);
}
@Component(modules = ActivityModule.class)
如何理解募谎?
上面已說明Component是注入器,并且是一個目標(biāo)類和目標(biāo)依賴實例的連接橋阴汇。而Module是創(chuàng)建類的工廠数冬。因此@Component(modules = ActivityModule.class)的含義就是ActivityModule.class為目標(biāo)類提供依賴實例,并通過MainComponent連接搀庶。
-
@Provides
dagger.Provides
Module中的創(chuàng)建類實例方法用Provides進(jìn)行標(biāo)注拐纱。
@Module
public class ActivityModule {
@Provides
public User provideUser(){
return new User("user from ActivityModule");
}
...
}
-
注解小結(jié):
個人認(rèn)為@Component
是Dagger2的核心注解铜异,因為其是目標(biāo)類和目標(biāo)依賴實例連接的橋梁,為方便理解將其當(dāng)作是注射器秸架,將目標(biāo)依賴實例注入到目標(biāo)類中揍庄。
Dagger2 使用
-
添加Dagger庫
Dagger主要是通過注解(annotation)及注解處理器實現(xiàn),因此需要添加兩個庫东抹,如下:
implementation 'com.google.dagger:dagger:2.+'
annotationProcessor 'com.google.dagger:dagger-compiler:2.+'
annotationProcessor
:注解處理器蚂子。
-
Demo代碼
(1)目標(biāo)依賴類
//User類
public class User {
public String name;
@Inject
public User(){
}
public User(String name){
this.name = name;
}
}
//Student 類
public class Student {
private String name;
@Inject
public Student() {
this.name = "小美";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//DaggerPresenter類
public class DaggerPresenter {
MainActivity activity;
User user;
public DaggerPresenter(MainActivity activity,User user){
this.user = user;
this.activity = activity;
}
public void showUserName(){
activity.showUserName(user.name);
}
}
(2)提供目標(biāo)依賴實例的Module類
此處提供的是自定義依賴實例,一般用于提供第三方依賴類的實例缭黔。
自定義依賴類的實例提供缆镣,可通過@Inject注解實現(xiàn)。
@Module
public class ActivityModule {
private MainActivity activity;
public ActivityModule(MainActivity activity) {
this.activity = activity;
}
@Provides
public MainActivity provideActivity(){
return activity;
}
@Provides
public User provideUser(){
return new User("user from ActivityModule");
}
@Provides
public DaggerPresenter provideDaggerPresenter(MainActivity activity,User user) {
return new DaggerPresenter(activity, user);
}
}
(3)注射器類
MainComponent.java
//情況1
@Component(modules = ActivityModule.class)
public interface MainComponent {
void inject(MainActivity activity);
}
//情況2:
@Component
public interface MainComponent {
void inject(MainActivity activity);
}
需要Module提供目標(biāo)依賴實例的情況试浙,需要按照情況1定義Component董瞻。
自定義Component類后,build項目田巴,并自動編譯生成相關(guān)類钠糊。如下圖:
如果想更好的理解Dagger2的依賴注入原理,可查看上圖中的相關(guān)代碼壹哺。這里推薦# 淺析Dagger2依賴注入實現(xiàn)過程抄伍。
(4)注入目標(biāo)類
public class MainActivity extends AppCompatActivity {
@Inject
Student student;
@Inject
DaggerPresenter presenter;
@Inject
User user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//*******關(guān)鍵代碼*******
DaggerMainComponent.builder().activityModule(new ActivityModule(this)).build().inject(this);
//*******關(guān)鍵代碼*******
TextView tv = findViewById(R.id.tv);
tv.setText(student.getName());
presenter.showUserName();
}
public void showUserName(String name) {
Toast.makeText(this,name,Toast.LENGTH_LONG).show();
}
}
到此為此,dagger基本使用完成了管宵。但是我還是留了個知識點未講哦??截珍。
在demo中在User類中的構(gòu)造函數(shù)上,添加了@Inject箩朴,但是添加/不添加 并沒有區(qū)別岗喉。為什么呢( ⊙o⊙?)
因為在MainModule類中,提供了User類的實例創(chuàng)建方法炸庞。而注解處理器在編譯過程中钱床,是先去找Module中是否有User的實例創(chuàng)建方法,如果找到了埠居,則User的實例由此方法創(chuàng)建查牌。如果沒有找到,再去User類中滥壕,去找是否有@Inject標(biāo)記的構(gòu)造方法纸颜。
根據(jù)此原理可知,Student類中的@Inject不能刪除绎橘。