一.Dagger2注入原理
Dagger2以自动生成代码的形式,帮助我们构建依赖图,在使用依赖的时候方便清晰,这里说明一点,在我们使用Dagger2的时候,绝大多数错误都是编译器就会暴漏出来,这也就决定了这套框架的稳定性会更高。
关于生成的源码,我们一起看一下。我们就以之前提到的例子来看:
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerApplicationComponent implements ApplicationComponent {
private Provider<Application> applicationProvider;
private Provider<Context> contextProvider;
private DaggerApplicationComponent(Builder builder) {
assert builder != null;
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
private void initialize(final Builder builder) {
this.applicationProvider = ApplicationModule_ApplicationFactory.create(builder.applicationModule);
this.contextProvider = ApplicationModule_ContextFactory.create(builder.applicationModule);
}
@Override
public Application application() {
return applicationProvider.get();
}
@Override
public Context context() {
return contextProvider.get();
}
public static final class Builder {
private ApplicationModule applicationModule;
private GsonModule gsonModule;
private Builder() {
}
public ApplicationComponent build() {
if (applicationModule == null) {
throw new IllegalStateException("applicationModule must be set");
}
if (gsonModule == null) {
this.gsonModule = new GsonModule();
}
return new DaggerApplicationComponent(this);
}
public Builder applicationModule(ApplicationModule applicationModule) {
if (applicationModule == null) {
throw new NullPointerException("applicationModule");
}
this.applicationModule = applicationModule;
return this;
}
public Builder gsonModule(GsonModule gsonModule) {
if (gsonModule == null) {
throw new NullPointerException("gsonModule");
}
this.gsonModule = gsonModule;
return this;
}
}
}
可以看到DaggerApplicationComponent中,有一个建造者模式来构建一个ApplicationComponent对象,这也帮我们初始化了两个Module中的依赖,但是注意,这里并没有直接初始化所有模块内的依赖,而只是初始化了组件对象而已。
可以看到initialize方法中有两个工厂方法。
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class ApplicationModule_ContextFactory implements Factory<Context> {
private final ApplicationModule module;
public ApplicationModule_ContextFactory(ApplicationModule module) {
assert module != null;
this.module = module;
}
@Override
public Context get() {
Context provided = module.context();
if (provided == null) {
throw new NullPointerException("Cannot return null from a non-@Nullable @Provides method");
}
return provided;
}
public static Factory<Context> create(ApplicationModule module) {
return new ApplicationModule_ContextFactory(module);
}
}
可以看出这个工厂中一直保留着ApplicationModule,当我们每次获取依赖,则会重新调用Module的context()方法,即如果里面是new的形式提供依赖 ,则会重新创建对象。
而反观我们用PerActivity标注的ToasterProvider:
@Generated("dagger.internal.codegen.ComponentProcessor")
public final class DaggerActivityComponent implements ActivityComponent {
private Provider<Context> contextProvider;
private MembersInjector<BaseActivity> baseActivityMembersInjector;
private Provider<Toaster> provideToasterProvider;
private Provider<Toaster> provideTheToasterProvider;
private DaggerActivityComponent(Builder builder) {
assert build