Dagger2 依赖注入之@Provides 分析

Dagger

下面主要分析,Dagger 中使用 @Provides 注解一个构造方法来提供依赖的过程。

举个栗子

老王再次开车去东北

还是那个老王

  • Person
public class Person {
    @Inject
    Car car;

    public void goDongbei(){
        car.run();
    }
}

一嗨租车

  • PersonModule
@Module
public class PersonModule {

    @Provides
    public Car provideCar(){
        return new Car();
    }
}

车子使用合约

  • PersonComponent
@Component(modules = PersonModule.class)
public interface PersonComponent {
    void inject(Person person);
}

GTR

  • Car
public class Car {
    private static final String TAG = "Car";
    
    public void run(){
        Log.d(TAG, "run: ~~~~~~");
    }
}

发动 GTR

此时,build一把工程,然后添加如下代码:

Person person = new Person();
DaggerPersonComponent.builder().build().inject(person);
person.goShopping();

向东北粗发

2019-04-17 16:35:08.602 5843-5843/? D/Car: run: 速度180,出发去东北

注入过程分析

问题又来了,Dagger 怎么凭借 DaggerPersonComponent.builder().build().inject(person) 一个链式调用就把 Car 对象注入到 Person 的呢?

先看看 DaggerPersonComponent 到底是什么?

DaggerPersonComponent 为工程 build 后 Dagger 利用注解自动生成的代码:

// Generated by dagger.internal.codegen.ComponentProcessor (https://google.github.io/dagger).
package com.example.di.component;

public final class DaggerPersonComponent implements PersonComponent {
  private Provider<Car> provideCarProvider;

  private MembersInjector<Person> personMembersInjector;

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

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

  public static PersonComponent create() {
    return builder().build();
  }

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

    this.provideCarProvider = PersonModule_ProvideCarFactory.create(builder.personModule);

    this.personMembersInjector = Person_MembersInjector.create(provideCarProvider);
  }

  @Override
  public void inject(Person person) {
    personMembersInjector.injectMembers(person);
  }

  public static final class Builder {
    private PersonModule personModule;

    private Builder() {}

    public PersonComponent build() {
      if (personModule == null) {
        this.personModule = new PersonModule();
      }
      return new DaggerPersonComponent(this);
    }

    public Builder personModule(PersonModule personModule) {
      this.personModule = Preconditions.checkNotNull(personModule);
      return this;
    }
  }
}

PersonModule 对象的创建

  1. 在构建DaggerPersonComponent时,显示的传入一个 PersonModule 对象,如下所示:

    DaggerPersonComponent.builder().personModule(new PersonModule()).build()

  2. 在构建DaggerPersonComponent时,不传 PersonModule 对象,如下所示:

    DaggerPersonComponent.builder().build()

    此时,Builder还是会自动构建一个 PersonModule 对象:

     public PersonComponent build() {
          if (personModule == null) {
    	this.personModule = new PersonModule();
          }
          return new DaggerPersonComponent(this);
        }
    

PersonModule 类是我们自己定义的,主要用来提供 car 对象。

PersonModule_ProvideCarFactory 对象的创建

使用简单工厂模式,创建一个 PersonModule_ProvideCarFactory 对象,该对象会持有 PersonModule 对象的引用,并提供一个 get 方法用来调用 module.provideCar(),源码如下:

public final class PersonModule_ProvideCarFactory implements Factory<Car> {
  private final PersonModule module;

  public PersonModule_ProvideCarFactory(PersonModule module) {
    assert module != null;
    this.module = module;
  }

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

  public static Factory<Car> create(PersonModule module) {
    return new PersonModule_ProvideCarFactory(module);
  }
}

PersonModule_ProvideCarFactory 对象可以看成是PersonModule对象的一个Wrapper。

Person_MembersInjector 对象的创建

使用简单工厂模式,创建一个 Person_MembersInjector 对象,该对象会持有 PersonModule_ProvideCarFactory 对象的引用,并提供一个 injectMembers 方法,源码如下:

public final class Person_MembersInjector implements MembersInjector<Person> {
  private final Provider<Car> carProvider;

  public Person_MembersInjector(Provider<Car> carProvider) {
    assert carProvider != null;
    this.carProvider = carProvider;
  }

  public static MembersInjector<Person> create(Provider<Car> carProvider) {
    return new Person_MembersInjector(carProvider);
  }

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

  public static void injectCar(Person instance, Provider<Car> carProvider) {
    instance.car = carProvider.get();
  }
}

Person_MembersInjector对象主要负责依赖的注入,上面的 injectMembers 方法就是给需要依赖的对象注入 car。

DaggerPersonComponent 对象的创建

当调用 DaggerPersonComponent.builder().build() 方法后,即会创建一个 DaggerPersonComponent 对象,源码如下:

    public PersonComponent build() {
      if (personModule == null) {
        this.personModule = new PersonModule();
      }
      return new DaggerPersonComponent(this);
    }

其实在创建 DaggerPersonComponent 对象过程中,已经顺带创建了 PersonModule 对象、PersonModule_ProvideCarFactory 以及 Person_MembersInjector 对象。

调用 DaggerPersonComponent 对象的 inject(person) 方法时,Person_MembersInjector 对象会从 PersonModule_ProvideCarFactory 获取 car 对象来注入给 person。

展开阅读全文

没有更多推荐了,返回首页