Dagger2是首个使用生成代码实现完整依赖注入的框架,极大减少了使用者的编码负担。
我们去看看Dagger2 是如何为我们注入对象的。
假设我们需要在MainActivity中注入对象DataManager:
public class MainActivity extends AppCompatActivity {
@Inject
DataManager dataManager;
}
使用@Inject标志被注入的对象dataManager(注意dataManager不能为private)
Dagger2中,负责提供依赖的组件被称为Module。
创建Module类,如下:
@Module
public class AppModule {
/**
* 带@Provides 注解 ,说明该方法是提供依赖
* @return
*/
@Provides
public DataManager provideManager() {
return new DataManager();
}
}
使用@Module注解来标识类型为module,并用@Provides标识提供依赖的方法。
Dagger2中,我们需要Component 来连接 Module 和 @Inject 来完成对象的注入:
创建 Component接口:
@Component(modules = {AppModule.class})
@Singleton
public interface AppComponent {
void inject(MainActivity activity);
}
使用@Component注解来标识类型为Component,参数modules 可以依赖多个module。
接口中的inject方法需要该注入对象所在的类作为参数。注意:这里必须是注入对象所在的类MainActivity,而不可以写成其父类。
编译。
Dagger2 会生成一些辅助类。
带@Component注解 :生成 Dagger_(带@Component注解接口名称)。这里是AppComponent。因此会生成 Dagger_AppComponent;
带@Module 注解 :生成 (带@Mudule类名)_(带@Provides注解的方法名)Factory。这里是 AppModule_ProvideManagerFactory
带@Inject 注解:生成 (需要注入对象所在的类名)_MembersInjector。
这里是MainActivity_MembersInjector。
类图:
在MainActivity中会调用以下代码:
DaggerAppComponent
.builder()
.appModule(new AppModule())
.build()
.inject(this);
去看看DaggerAppComponent源码:
- 调用build方法创建出DaggerAppComponent实例。
- 在创建DaggerAppComponent实例时,调用了initialize(builder),创建AppModule_ProvideManagerFactory 和MainActivity_MembersInjector 实例,调用了相对应create的方法。
MainActivity_MembersInjector 源码:
调用create的方法创建实例时 传入了 AppModule_ProvideManagerFactory 作为参数。
但 .inject(this)方法时,调用了injectMembers方法,看到这个方法,可以知道为什么datamanage 不能为private和为什么调用inject方法传参数时不能写父类了。
dataManage 实例的创建调用了AppModule_ProvideManagerFactory的get方法。
看看AppModule_ProvideManagerFactory的源码:
可以看到,get方法其实调用了AppModule 的provideManager方法,而这个方法new DataManager();完成对象的注入。
这就是Dagger2 为我们注入对象处理的流程。
我们在MainActivity 再注入一个对象Person,看看Dagger2 生成了怎么样的辅助类。
修改如下:
MainActivity :
public class MainActivity extends AppCompatActivity {
@Inject
DataManager dataManager;
@Inject
Person person;
}
修改AppModule:
@Module
public class AppModule {
/**
* 带@Provides 注解 ,说明该方法是提供依赖
* @return
*/
@Provides
public DataManager provideManager() {
return new DataManager();
}
@Provides
public Person providePerson(){
return new Person();
}
}
类图:
如果是多层依赖 又会生成什么辅助类?
添加 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;
}
类图:
可以看出
- Component 只是 Module 和 Inject 中间的桥梁
- Module 相当于简单工厂,提供了各种依赖
辅助类的生成规则:
带@Component注解 :生成 Dagger_(带@Component注解接口名称)。这里是AppComponent。因此会生成 Dagger_AppComponent;
带@Module 注解 :生成 (带@Mudule类名)_(带@Provides注解的方法名)Factory。这里是 AppModule_ProvideManagerFactory
带@Inject 注解:生成 (需要注入对象所在的类名)_MembersInjector。
这里是MainActivity_MembersInjector。
END。