Dagger2是首個(gè)使用生成代碼實(shí)現(xiàn)完整依賴(lài)注入的框架,極大減少了使用者的編碼負(fù)擔(dān)。
我們?nèi)タ纯碊agger2 是如何為我們注入對(duì)象的。
假設(shè)我們需要在MainActivity中注入對(duì)象DataManager:
public class MainActivity extends AppCompatActivity {
@Inject
DataManager dataManager;
}
使用@Inject標(biāo)志被注入的對(duì)象dataManager(注意dataManager不能為private)
Dagger2中浮还,負(fù)責(zé)提供依賴(lài)的組件被稱(chēng)為Module。
創(chuàng)建Module類(lèi)闽巩,如下:
@Module
public class AppModule {
/**
* 帶@Provides 注解 ,說(shuō)明該方法是提供依賴(lài)
* @return
*/
@Provides
public DataManager provideManager() {
return new DataManager();
}
}
使用@Module注解來(lái)標(biāo)識(shí)類(lèi)型為module担汤,并用@Provides標(biāo)識(shí)提供依賴(lài)的方法涎跨。
Dagger2中,我們需要Component 來(lái)連接 Module 和 @Inject 來(lái)完成對(duì)象的注入:
創(chuàng)建 Component接口:
@Component(modules = {AppModule.class})
@Singleton
public interface AppComponent {
void inject(MainActivity activity);
}
使用@Component注解來(lái)標(biāo)識(shí)類(lèi)型為Component崭歧,參數(shù)modules 可以依賴(lài)多個(gè)module隅很。
接口中的inject方法需要該注入對(duì)象所在的類(lèi)作為參數(shù)。注意:這里必須是注入對(duì)象所在的類(lèi)MainActivity率碾,而不可以寫(xiě)成其父類(lèi)叔营。
編譯。
Dagger2 會(huì)生成一些輔助類(lèi)所宰。
帶@Component注解 :生成 Dagger_(帶@Component注解接口名稱(chēng))绒尊。這里是AppComponent。因此會(huì)生成 Dagger_AppComponent仔粥;
帶@Module 注解 :生成 (帶@Mudule類(lèi)名)_(帶@Provides注解的方法名)Factory婴谱。這里是 AppModule_ProvideManagerFactory
帶@Inject 注解:生成 (需要注入對(duì)象所在的類(lèi)名)_MembersInjector。
這里是MainActivity_MembersInjector躯泰。
類(lèi)圖:
在MainActivity中會(huì)調(diào)用以下代碼:
DaggerAppComponent
.builder()
.appModule(new AppModule())
.build()
.inject(this);
去看看DaggerAppComponent源碼:
- 調(diào)用build方法創(chuàng)建出DaggerAppComponent實(shí)例谭羔。
- 在創(chuàng)建DaggerAppComponent實(shí)例時(shí),調(diào)用了initialize(builder)麦向,創(chuàng)建AppModule_ProvideManagerFactory 和MainActivity_MembersInjector 實(shí)例瘟裸,調(diào)用了相對(duì)應(yīng)create的方法。
MainActivity_MembersInjector 源碼:
調(diào)用create的方法創(chuàng)建實(shí)例時(shí) 傳入了 AppModule_ProvideManagerFactory 作為參數(shù)诵竭。
但 .inject(this)方法時(shí)话告,調(diào)用了injectMembers方法兼搏,看到這個(gè)方法,可以知道為什么datamanage 不能為private和為什么調(diào)用inject方法傳參數(shù)時(shí)不能寫(xiě)父類(lèi)了超棺。
dataManage 實(shí)例的創(chuàng)建調(diào)用了AppModule_ProvideManagerFactory的get方法向族。
看看AppModule_ProvideManagerFactory的源碼:
可以看到,get方法其實(shí)調(diào)用了AppModule 的provideManager方法棠绘,而這個(gè)方法new DataManager()件相;完成對(duì)象的注入。
這就是Dagger2 為我們注入對(duì)象處理的流程氧苍。
我們?cè)贛ainActivity 再注入一個(gè)對(duì)象Person夜矗,看看Dagger2 生成了怎么樣的輔助類(lèi)。
修改如下:
MainActivity :
public class MainActivity extends AppCompatActivity {
@Inject
DataManager dataManager;
@Inject
Person person;
}
修改AppModule:
@Module
public class AppModule {
/**
* 帶@Provides 注解 让虐,說(shuō)明該方法是提供依賴(lài)
* @return
*/
@Provides
public DataManager provideManager() {
return new DataManager();
}
@Provides
public Person providePerson(){
return new Person();
}
}
類(lèi)圖:
如果是多層依賴(lài) 又會(huì)生成什么輔助類(lèi)紊撕?
添加 UserModule :
@Module
public class UserModule {
@Provides
public User provideUser(){
return new User();
}
}
修改AppComponent
@Component(modules = {AppModule.class,UserModule.class})
@Singleton
public interface AppComponent {
void inject(MainActivity activity);
}
修改MainActivity
public class MainActivity extends AppCompatActivity {
@Inject
DataManager dataManager;
@Inject
Person person;
@Inject
User user;
}
類(lèi)圖:
可以看出
- Component 只是 Module 和 Inject 中間的橋梁
- Module 相當(dāng)于簡(jiǎn)單工廠,提供了各種依賴(lài)
輔助類(lèi)的生成規(guī)則:
帶@Component注解 :生成 Dagger_(帶@Component注解接口名稱(chēng))。這里是AppComponent赡突。因此會(huì)生成 Dagger_AppComponent对扶;
帶@Module 注解 :生成 (帶@Mudule類(lèi)名)_(帶@Provides注解的方法名)Factory。這里是 AppModule_ProvideManagerFactory
帶@Inject 注解:生成 (需要注入對(duì)象所在的類(lèi)名)_MembersInjector惭缰。
這里是MainActivity_MembersInjector浪南。
END。