Dagger2代码分析理解Component和Module

Dagger2主要有如下几个核心概念:

@Component

@Module

@Inject

@Singleton

很多同学在学习Dagger2时都知道如何使用,但可能知其然而不知其所以然,本文以Dagger2官方例子,通过分析生成后代码,帮助大家加深对上述概念的理解:

Dagger2代码分析理解Component和Module_第1张图片
coffee.png

CoffeeShop.java

@Singleton
@Component(modules = {DripCoffeeModule .class})
public interface CoffeeShop {
  void inject(MyApplication application);
}

DripCoffeeModule.java

@Module
public class DripCoffeeModule {

  @Provides
  Heater provideHeater() {
    return new ElectricHeater();
  }

  @Provides
  Pump providePump(Thermosiphon pump) {
    return pump;
  }
}

CoffeeShop.java编译生成DaggerCoffeeShop.java,代码比较冗长读者可以不需要细看,主要包含成员变量,initialize方法,Builder类三部分。

public final class DaggerCoffeeShop implements CoffeeShop {

  private MembersInjector myApplicationMembersInjector;

  private Provider provideHeaterProvider;

  private Provider thermosiphonProvider;

  private Provider providePumpProvider;

  private MembersInjector coffeeMakerMembersInjector;

  private Provider coffeeMakerProvider;

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

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

  public static CoffeeShop create() {
    return new Builder().build();
  }

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

    this.myApplicationMembersInjector =
        MyApplication_MembersInjector.create(dispatchingAndroidInjectorProvider);

    this.provideHeaterProvider =
        DripCoffeeModule_ProvideHeaterFactory.create(builder.dripCoffeeModule);

    this.thermosiphonProvider =
        DoubleCheck.provider(Thermosiphon_Factory.create(provideHeaterProvider));

    this.providePumpProvider =
        DripCoffeeModule_ProvidePumpFactory.create(builder.dripCoffeeModule, thermosiphonProvider);

    this.coffeeMakerMembersInjector =
        CoffeeMaker_MembersInjector.create(provideHeaterProvider, providePumpProvider);

    this.coffeeMakerProvider =
        DoubleCheck.provider(
            CoffeeMaker_Factory.create(
                coffeeMakerMembersInjector, provideHeaterProvider, providePumpProvider));
  }

  @Override
  public void inject(MyApplication application) {
    myApplicationMembersInjector.injectMembers(application);
  }

  public static final class Builder {
    private DripCoffeeModule dripCoffeeModule;

    private Builder() {}

    public CoffeeShop build() {
      if (dripCoffeeModule == null) {
        this.dripCoffeeModule = new DripCoffeeModule();
      }
      return new DaggerCoffeeShop(this);
    }

    public Builder dripCoffeeModule(DripCoffeeModule dripCoffeeModule) {
      this.dripCoffeeModule = Preconditions.checkNotNull(dripCoffeeModule);
      return this;
    }
  }



从上述生成的代码看,我们可以知道

  1. Component从module加载生成所有的创建对象的Factory create mehod。
   private Provider provideHeaterProvider;  

    this.provideHeaterProvider =
        DripCoffeeModule_ProvideHeaterFactory.create(builder.dripCoffeeModule);

    this.thermosiphonProvider =
        DoubleCheck.provider(Thermosiphon_Factory.create(provideHeaterProvider));

2.如果标记为@Singleton,则会生成DoubleCheck.provider()保证创建为单例模式

    this.coffeeMakerProvider =
        DoubleCheck.provider(
            CoffeeMaker_Factory.create(
                coffeeMakerMembersInjector, provideHeaterProvider, providePumpProvider));

3.内部类Builder负责创建component依赖的所有Module

  public static final class Builder {
    private DripCoffeeModule dripCoffeeModule;

    private Builder() {}

    public CoffeeShop build() {
      if (dripCoffeeModule == null) {
        this.dripCoffeeModule = new DripCoffeeModule();
      }
      return new DaggerCoffeeShop(this);
    }

    public Builder dripCoffeeModule(DripCoffeeModule dripCoffeeModule) {
      this.dripCoffeeModule = Preconditions.checkNotNull(dripCoffeeModule);
      return this;
    }
  }

4.如果对构造函数标记为@Inject,则会自动生成MembersInjector类

CoffeeMaker.java

@Singleton
public class CoffeeMaker {
    @Inject Heater heater;

    @Inject Pump pump;

    @Inject
    public CoffeeMaker(Heater heater, Pump pump) {
        Log.i("wenson", "CoffeeMake create");
        this.heater = heater;
        this.pump = pump;
    }

    public void brew(){

    }
}

Component类生成对应的方法,其中包含CoffeeMaker_MembersInjector 和 CoffeeMaker_Factory这2个负责实际创建的类。

  private MembersInjector coffeeMakerMembersInjector;

    this.coffeeMakerMembersInjector =
        CoffeeMaker_MembersInjector.create(provideHeaterProvider, providePumpProvider);

    this.coffeeMakerProvider =
        DoubleCheck.provider(
            CoffeeMaker_Factory.create(
                coffeeMakerMembersInjector, provideHeaterProvider, providePumpProvider));

查看生成的CoffeeMaker_MembersInjector类, 这个类负责对象的具体创建

public final class CoffeeMaker_MembersInjector implements MembersInjector {
  private final Provider heaterProvider;

  private final Provider pumpProvider;

  public CoffeeMaker_MembersInjector(Provider heaterProvider, Provider pumpProvider) {
    assert heaterProvider != null;
    this.heaterProvider = heaterProvider;
    assert pumpProvider != null;
    this.pumpProvider = pumpProvider;
  }

  public static MembersInjector create(
      Provider heaterProvider, Provider pumpProvider) {
    return new CoffeeMaker_MembersInjector(heaterProvider, pumpProvider);
  }

  @Override
  public void injectMembers(CoffeeMaker instance) {
    if (instance == null) {
      throw new NullPointerException("Cannot inject members into a null reference");
    }
    instance.heater = heaterProvider.get();
    instance.pump = pumpProvider.get();
  }

  public static void injectHeater(CoffeeMaker instance, Provider heaterProvider) {
    instance.heater = heaterProvider.get();
  }

  public static void injectPump(CoffeeMaker instance, Provider pumpProvider) {
    instance.pump = pumpProvider.get();
  }
}

查看生成的CoffeeMaker_Factory类,主要负责对象创建的再封装

public final class CoffeeMaker_Factory implements Factory {
  private final MembersInjector coffeeMakerMembersInjector;

  private final Provider heaterProvider;

  private final Provider pumpProvider;

  public CoffeeMaker_Factory(
      MembersInjector coffeeMakerMembersInjector,
      Provider heaterProvider,
      Provider pumpProvider) {
    assert coffeeMakerMembersInjector != null;
    this.coffeeMakerMembersInjector = coffeeMakerMembersInjector;
    assert heaterProvider != null;
    this.heaterProvider = heaterProvider;
    assert pumpProvider != null;
    this.pumpProvider = pumpProvider;
  }

  @Override
  public CoffeeMaker get() {
    return MembersInjectors.injectMembers(
        coffeeMakerMembersInjector, new CoffeeMaker(heaterProvider.get(), pumpProvider.get()));
  }

  public static Factory create(
      MembersInjector coffeeMakerMembersInjector,
      Provider heaterProvider,
      Provider pumpProvider) {
    return new CoffeeMaker_Factory(coffeeMakerMembersInjector, heaterProvider, pumpProvider);
  }
}

总结:

  • Dagger的优点是是编译期静态生成对象依赖注入的所有代码,不是运行时动态反射方式。

  • 优点是运行时无性能副作用,缺点是编译后生成大量类,对象注入需要指定类,生成对应的类方法。

  • 即使使用google的AndroidInjector, 也只是方便开发人员少写一部分代码。

从以上代码分析可以帮助我们更深刻得理解Component和Module的概念。

  • 打个比方:Component类似注射器,Module是连接注射器的各个原料工厂。

  • 我们可以定义各种原料工厂(Module), 有网络的NetModule(Retrofit),有存储的DBModule(Room)等等。

看上述代码很累的同学,建议将Dagger2官方例子导入到工程里实际编译阅读,方便理解。

你可能感兴趣的:(Dagger2代码分析理解Component和Module)