Dagger2注入原理

这里根据简单基础的注入来分析一些基础注入的原理。不明白基础的请看上一篇重新认识Dagger2文章


Dagger2是通过apt插件在编译阶段生成相应的注入代码的。在完成上面那个例子Rebuild Project编译成功之后,Dagger2会在/app/build/generated/apt/debug/目录下生成一些对应的工厂类


我们看下面具体代码,我们先看MainPersenter这个类,这个类中的构造函数中用了@Inject标注

@Inject
MainPersenter(MainView.View view) {
    mView = view;
}

编译成功之后MainPersenter也在 MainPresenter_Factory生成相对应的代码

public final class MainPersenter_Factory implements Factory<MainPersenter> {
  private final Provider<MainView.View> viewProvider;

  public MainPersenter_Factory(Provider<MainView.View> viewProvider) {
    assert viewProvider != null;
    this.viewProvider = viewProvider;
  }

  @Override
  public MainPersenter get() {
    return new MainPersenter(viewProvider.get());
  }

  public static Factory<MainPersenter> create(Provider<MainView.View> viewProvider) {
    return new MainPersenter_Factory(viewProvider);
  }
}

有个viewProvide是Provider类型,在构造函数实例化,泛型参数是MainView.View,看到Provider应该就知道MainView.View是一个依赖,而这个依赖的提供着就是MainModule了,所以这个viewProvide是由MainModule提供的。看源码可以看到有个get()方法,里面是MainPersenter的实例化,构造函数里面的参数就是MainView.View,由viewProvider.get()提供,然后就是create方法创建MainPersenter_Factory类,由此得出viewProvider是由MainModule提供的,接下来看看MainModule对应的注入类。

@Provides
MainView.View provideMainView() {
    return mView;
}

在MainModule中定义的@Provides修饰的方法会对应的生成一个工厂类

public final class MainModule_ProvideMainViewFactory implements Factory<MainView.View> {
  private final MainModule module;

  public MainModule_ProvideMainViewFactory(MainModule module) {
    assert module != null;
    this.module = module;
  }

  @Override
  public MainView.View get() {
    return Preconditions.checkNotNull(
        module.provideMainView(), "Cannot return null from a non-@Nullable @Provides method");
  }

  public static Factory<MainView.View> create(MainModule module) {
    return new MainModule_ProvideMainViewFactory(module);
  }
}

跟MainModule是相对应的就是这个MainModule_ProvideMainViewFactory类,下面的get()方法,内部调用的就是MainModule里面的 provideMainView()方法来返回所需要的MainView.View依赖,看回MainPresenter_Factory里的get()方法中,实例化MainPresenter时候的参数是viewProvider.get(),看到这些可以得到,原来那个viewProvider就是生成的MainModule_ProvideMainViewFactory,然后调用了其get()方法,将我们需要的MainContract.View依赖注入到MainPresenter里。这就是MainPresenter的实例化过程了,MainPresenter会对应的有一个工厂类,在这个类的get()方法中进行MainPresenter创建,而MainPresenter所需要的MainView.View依赖,是由MainModule里定义的以@Provide开头的方法所对应的工厂类提供的。这是实例化的过程,那create方法又是怎么跟@Inject标注MainPersenter关联起来,前面说过Component是连接@Module和@Inject的桥梁,那就是Component了,下面看看代码:

@Component(modules = MainModule.class)
public interface MainComponent {
    void inject(MainActivity activity);
}

public final class DaggerMainComponent implements MainComponent {
  private Provider<MainView.View> provideMainViewProvider;

  private Provider<MainPersenter> mainPersenterProvider;

  private MembersInjector<MainActivity> mainActivityMembersInjector;

  private DaggerMainComponent(Builder builder) {
    assert builder != null;
    initialize(builder);
  }

  public static Builder builder() {
    return new Builder();
  }

  @SuppressWarnings("unchecked")
  private void initialize(final Builder builder) {

    this.provideMainViewProvider = MainModule_ProvideMainViewFactory.create(builder.mainModule);

    this.mainPersenterProvider = MainPersenter_Factory.create(provideMainViewProvider);

    this.mainActivityMembersInjector = MainActivity_MembersInjector.create(mainPersenterProvider);
  }

  @Override
  public void inject(MainActivity activity) {
    mainActivityMembersInjector.injectMembers(activity);
  }

  public static final class Builder {
    private MainModule mainModule;

    private Builder() {}

    public MainComponent build() {
      if (mainModule == null) {
        throw new IllegalStateException(MainModule.class.getCanonicalName() + " must be set");
      }
      return new DaggerMainComponent(this);
    }

    public Builder mainModule(MainModule mainModule) {
      this.mainModule = Preconditions.checkNotNull(mainModule);
      return this;
    }
  }
}

从上面的代码可以看到,我们之前定义的MainComponent方法会生成一个对应的DaggerMainComponent类,并且实现了MainComponent类,在生成的代码中也有Provider所提供的依赖,它们靠MainComponent关联起来,是靠initialize方法实例化的,创建了MainModule_ProvideMainViewFactory用来提供MainView.View依赖,然后将provideMainViewProvider传递给MainPersenter_Factory,就是前面说的viewProvider,接着将这个mainPresenterProvider又传递到MainActivity_MembersInjector中进行实例化,我们可以想到这就是MainActivity相对应的注入类。

这里我们先看看create()方法,返回的是Factory类型,而provideMainViewProvider是个Provider类型,其实看源码就明白了,Factory仅仅继承一个Provider,并是一个空的实现。

public interfaceFactory<T> extends Provider<T> {} 

接着是我们在MainComponent里定义的Inject方法的实现,这里调用了mainActivityMembersInjector.injectMembers(activity)方法,将我们的MainActivity注入到该类中。看看injectMembers方法

/**
 * Injects dependencies into the fields and methods on instances of type {@code T}. Ignores the
 * presence or absence of an injectable constructor.
 *
 * @param <T> type to inject members of
 *
 * @author Bob Lee
 * @author Jesse Wilson
 * @since 2.0 (since 1.0 without the provision that {@link #injectMembers} cannot accept
 *      {@code null})
 */
public interface MembersInjector<T> {

  /**
   * Injects dependencies into the fields and methods of {@code instance}. Ignores the presence or
   * absence of an injectable constructor.
   *
   * <p>Whenever the object graph creates an instance, it performs this injection automatically
   * (after first performing constructor injection), so if you're able to let the object graph
   * create all your objects for you, you'll never need to use this method.
   *
   * @param instance into which members are to be injected
   * @throws NullPointerException if {@code instance} is {@code null}
   */
  void injectMembers(T instance);
}

从类的注释中,可以看出它的主要作用是给类的属性字段,或者方法参数来提供注入,并忽略是否在含有构造器的注入,都会生成MembersInjector的类。

接着就是Builder内部类,用来创建我们的module以及自身实例。在build() 方法里面主要用来初始化DaggerMainComponent再去初始化依赖,而真正的将这些依赖于Inject关联起来的就是MainActivity_MembersInjector类,看看这个类里做了什么。

public final class MainActivity_MembersInjector implements MembersInjector<MainActivity> {
  private final Provider<MainPersenter> mainPresenterProvider;

  public MainActivity_MembersInjector(Provider<MainPersenter> mainPresenterProvider) {
    assert mainPresenterProvider != null;
    this.mainPresenterProvider = mainPresenterProvider;
  }

  public static MembersInjector<MainActivity> create(
      Provider<MainPersenter> mainPresenterProvider) {
    return new MainActivity_MembersInjector(mainPresenterProvider);
  }

  @Override
  public void injectMembers(MainActivity instance) {
    if (instance == null) {
      throw new NullPointerException("Cannot inject members into a null reference");
    }
    instance.mainPresenter = mainPresenterProvider.get();
  }

  public static void injectMainPresenter(
      MainActivity instance, Provider<MainPersenter> mainPresenterProvider) {
    instance.mainPresenter = mainPresenterProvider.get();
  }
}

这个类的最重要的就是injectMembers()方法,就在刚才提到的DaggerMainComponent类中的inject()方法里也调用了,所以这里的instance实例是由DaggerMainComponent提供的,然后我们看到下面一句关键的代码

instance.mainPresenter= mainPresenterProvider.get();

从上方可以看出,MainActivity_MembersInjector类通过实现MembersInjector类,通过injectMembers方法将mainPresenterProvider中创建好的MainPresenter实例赋值给instance(MainActivity)的成员mainPresenter,采用Provider获取实例的方式,来给我们之前定义的Inject参数或者属性,来赋值相应的注入类。接着就可以在代码中使用了。到这里,就分析完了Dagger2的注入过程



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值