Dagger2入坑之旅 二

本文接前一篇Dagger2入坑之旅 一

前文说到了dagger2的基本使用方法,但是乍一看却很疑惑,心中有疑惑,为什么这么写?下面一一解释
我们来重新理一遍上面的注入过程,首先弄清楚以下几个概念:

  • @Inject 带有此注解的属性或构造方法将参与到依赖注入中,Dagger2会实例化有此注解的类

  • @Module 带有此注解的类,用来提供依赖,里面定义一些用@Provides注解的以provide开头的方法,这些方法就是所提供的依赖,Dagger2会在该类中寻找实例化某个类所需要的依赖。

  • @Component 用来将@Inject@Module联系起来的桥梁,从@Module中获取依赖并将依赖注入给@Inject

先看看Vehicle的生成类 :

@Generated(
  value = "dagger.internal.codegen.ComponentProcessor",
  comments = "https://google.github.io/dagger"
)
public final class Vehicle_Factory implements Factory<Vehicle> {
  private final Provider motorProvider;

  public Vehicle_Factory(Provider motorProvider) {
    assert motorProvider != null;
    this.motorProvider = motorProvider;
  }

  @Override
  public Vehicle get() {
    return new Vehicle(motorProvider.get());
  }

  public static Factory create(Provider motorProvider) {
    return new Vehicle_Factory(motorProvider);
  }
}

检阅代码,可以看到Vehicle_Factory里有一个motorProvider的变量,get()和create方法;这里就会有疑问了为什么这个motorProvider不是’Motor’类型而是’Provider’;可以看到Vehicle是个依赖而提供这个依赖的是VehicleModule因此这个motorProvide一定是VehicleModule提供的;在看看get方法,可以发现原来Vehicle实例化是在这里进行的; 而create方法是用来创建Vehicle_Factory这个类的;

然后在看VehicleModule 生成的代码类:
由于VehicleModule这个类里实现了两个@Provides所以AS为为我们生成了两个类,因为例子里只用到了VehicleModule_ProviceVehicleFactory 所以这里只介绍这个类
Dagger2入坑之旅 二_第1张图片

@Generated(
  value = "dagger.internal.codegen.ComponentProcessor",
  comments = "https://google.github.io/dagger"
)
public final class VehicleModule_ProviceVehicleFactory implements Factory<Vehicle> {
  private final VehicleModule module;

  public VehicleModule_ProviceVehicleFactory(VehicleModule module) {
    assert module != null;
    this.module = module;
  }

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

  public static Factory create(VehicleModule module) {
    return new VehicleModule_ProviceVehicleFactory(module);
  }
}

可以看到VehicleModule_ProviceVehicleFactory的 get()方法的调用VehicleModule.proviceVehicle()方法并且返回的类型是Vehicle 这个时候就很明白了,原来创建Vehicle的就是这个get()方法;

看到这里我们应该明白了Vehicle的实例化过程。Vehicle会对应的有一个工厂类,在这个类的get()方法中进行Vehicle创建,而Vehicle所需要的View依赖,是由VehicleModule里定义的以provide开头的方法所对应的工厂类提供的;

此时虽然我们明白了实例化创建,但是VehicleModule_ProviceVehicleFactory的create()方法哪里调用的呢?此时创建的Vehicle实例是怎么跟@Inject注解的Vehicle关联起来的?这个时候就要说到 @Component了,Component是连接@Module和@Inject的桥梁,在说到VehicleComponent我们先在MainActivity里加上

@Inject
Vehicle vehicle;

然后点击make project然后AndroidStudio会为我们生成MainActivity_MembersInjector类代码如下:

@Generated(
  value = "dagger.internal.codegen.ComponentProcessor",
  comments = "https://google.github.io/dagger"
)
public final class MainActivity_MembersInjector implements MembersInjector {
  private final Provider vehicleProvider;

  public MainActivity_MembersInjector(Provider vehicleProvider) {
    assert vehicleProvider != null;
    this.vehicleProvider = vehicleProvider;
  }

  public static MembersInjector create(Provider vehicleProvider) {
    return new MainActivity_MembersInjector(vehicleProvider);
  }

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

  public static void injectVehicle(MainActivity instance, Provider vehicleProvider) {
    instance.vehicle = vehicleProvider.get();
  }
}

可以看到该类里有个Provider类型的参数vehicleProvider,该参数在MainActivity_MembersInjector的构造函数里被赋值;然后在看injectMembers()方法 这个时候就很明白了MainActivity里的vehicle到底是怎么初始化了,是由vehicleProvider.get();生成 ;

然后我们再看看VehicleComponent生成的类 DaggerVehicleComponent

@Generated(
  value = "dagger.internal.codegen.ComponentProcessor",
  comments = "https://google.github.io/dagger"
)
public final class DaggerVehicleComponent implements VehicleComponent {
  private Provider proviceVehicleProvider;

  private MembersInjector mainActivityMembersInjector;

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

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

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

    this.proviceVehicleProvider =
        ScopedProvider.create(VehicleModule_ProviceVehicleFactory.create(builder.vehicleModule));

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

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

  public static final class Builder {
    private VehicleModule vehicleModule;

    private Builder() {}

    public VehicleComponent build() {
      if (vehicleModule == null) {
        throw new IllegalStateException(VehicleModule.class.getCanonicalName() + " must be set");
      }
      return new DaggerVehicleComponent(this);
    }

    public Builder vehicleModule(VehicleModule vehicleModule) {
      this.vehicleModule = Preconditions.checkNotNull(vehicleModule);
      return this;
    }
  }
}

这个时候就很清楚了,在Build类里对VehicleModule进行了创建;然后在initialize()方法里对VehicleModule_ProviceVehicleFactory和MainActivity_MembersInjector创建,前面说过Component是连接@Module和@Inject的桥梁这里只是对他们进行了创建,并没有关联起来;真正把他们关联起来的地方在inject()方法里 ,so在MainActivity里只要这么写就可以使用了

 DaggerVehicleComponent.builder()
                .vehicleModule(new VehicleModule(new Motor()))
                .build()
                .inject(this);

这样下来就懂了dagger2到底是怎么工作的了;只要弄懂原理,怎么使用就会明白了

Dagger2入坑之旅 三 项目实战

你可能感兴趣的:(android)