Dagger2源码分析-最简单的注入过程
Dagger2最简单的依赖注入实践
要实现三个类:
- Dagger2Activity
- ActivityComponent
- ActivityModule
直接上代码:
1、Dagger2Activity
public class Dagger2Activity extends Activity {
private ActivityComponent mActivityComponent;
@Inject
UserModel mUserModel;
@Bind(R.id.tv_user_id)
TextView tvUserId;
@Bind(R.id.tv_user_name)
TextView tvUserName;
@Bind(R.id.tv_user_gender)
TextView tvUserGender;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ex_dagger2_activity);
ButterKnife.bind(this);
mActivityComponent = DaggerActivityComponent.builder().activityModule(new ActivityModule(1, "Leon", 1)).build();
mActivityComponent.inject(this);
tvUserId.setText(mUserModel.id + "");
tvUserName.setText(mUserModel.name);
tvUserGender.setText(mUserModel.gender + "");
}
}
2、ActivityComponent
@Component(modules = ActivityModule.class)
public interface ActivityComponent {
void inject(Dagger2Activity activity);
}
3、ActivityModule
@Module
public class ActivityModule {
private UserModel mUserModel;
public ActivityModule(long userId, String userName, int gender) {
mUserModel = new UserModel(userId, userName, gender);
}
@Provides
UserModel provideUserModel() {
return mUserModel;
}
}
列出所有类
使用Dagger,要实现
Dagger2Activity
、ActivityComponent
、ActivityModule
三个类,Make Project之后生成三个类:
- DaggerActivityComponent
- Dagger2Activity_MemberInject
- ActivityModule_ProviderUserModelFactory
分析代码
注入程序的入口
mActivityComponent.inject(this);
@Component(modules = ActivityModule.class)
public interface ActivityComponent {
void inject(ExDagger2Activity activity);
}
直接调用的是ActivityComponent的inject。ActivityComponent是个接口,实现类是DaggerActivityComponent。
@Override
public void inject(ExDagger2Activity activity) {
exDagger2ActivityMembersInjector.injectMembers(activity);
}
注意,inject接收被注入的实例参数。接下来的DaggerActivityComponent的注入工作应该是:
- 找到被注入的Activity中被@Inject注解的成员mUserModel变量;
- 然后赋值给mUserModel
DaggerActivityComponent有两个成员变量:
private Provider<UserModel> provideUserModelProvider;//负责提供对象
private MembersInjector<ExDagger2Activity> dagger2ActivityMembersInjector;//负责给被@Inject的成员变量赋值
赋值给被@Inject的成员变量
DaggerActivityComponent的inject调用的是dagger2ActivityMembersInjector的injectMembers,实现如下:
Dagger2Activity_MembersInjector.java
@Override
public void injectMembers(ExDagger2Activity instance) {
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
instance.mUserModel = mUserModelProvider.get();
}
从mUserModelProvider中获取对象赋值给被注入类Dagger2Activity的mUserModel成员变量(所以,mUserModel必须是public的)。
mUserModelProvider从哪里来的?
DaggerActivityComponent.java
private void initialize(final Builder builder) {
this.provideUserModelProvider =
ActivityModule_ProvideUserModelFactory.create(builder.activityModule);
this.exDagger2ActivityMembersInjector =
ExDagger2Activity_MembersInjector.create(provideUserModelProvider);
}
DaggerActivityComponent初始化他的两个成员变量时,传入的。也就是说,赋值提供对象的是provideUserModelProvider(看名字也知道了)。
轮到ActivityModule发挥作用了:创建对象
ActivityModule生成了一个工厂类ActivityModule_ProvideUserModelFactory。这个工厂类是专门生产UserModel对象的。
@Module
public class ActivityModule {
private UserModel mUserModel;
public ActivityModule(long userId, String userName, int gender) {
mUserModel = new UserModel(userId, userName, gender);
}
@Provides
UserModel provideUserModel() {
return mUserModel;
}
}
@Generated(
value = "dagger.internal.codegen.ComponentProcessor",
comments = "https://google.github.io/dagger"
)
public final class ActivityModule_ProvideUserModelFactory implements Factory<UserModel> {
private final ActivityModule module;
public ActivityModule_ProvideUserModelFactory(ActivityModule module) {
assert module != null;
this.module = module;
}
@Override
public UserModel get() {
return Preconditions.checkNotNull(
module.provideUserModel(), "Cannot return null from a non-@Nullable @Provides method");
}
public static Factory<UserModel> create(ActivityModule module) {
return new ActivityModule_ProvideUserModelFactory(module);
}
}
放在一起对比。ActivityModule的provideUserModel方法创建了对象,被ActivityModule_ProvideUserModelFactory的get方法获取。
总结
分析完代码之后,再看看文章开头的类图。Make Project之后生产三个类的作用分别是:
- DaggerActivityComponent:程序入口,负责串联创建对象与赋值。
- Dagger2Activity_MemberInject:持有被注入的对象DaggerActivity,赋值给被@Inject的成员变量。
- ActivityModule_ProviderUserModelFactory:创建对象。