Skip to content

Latest commit

 

History

History
132 lines (80 loc) · 3.83 KB

Pattern_ProviderInDagger.md

File metadata and controls

132 lines (80 loc) · 3.83 KB

Dagger 中的设计模式分析

简单工厂模式

使用 @Inject 注解一个构造函数

当我们使用 @Inject 来注解一个类(Car)的构造函数时,build 项目后,Dagger 会自动生成一个 Car_Factory 类,源码如下:

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

public final class Car_Factory implements Factory<Car> {
  // 恶汉单例,确保线程安全
  private static final Car_Factory INSTANCE = new Car_Factory();

  @Override
  public Car get() {
    return new Car();
  }

  public static Factory<Car> create() {
    return INSTANCE;
  }

  /** Proxies {@link Car#Car()}.*/
  public static Car newCar() {
    return new Car();
  }
}
  1. Car_Factory类的构造采用恶汉单例模式,即当虚拟机加载 Car_Factory 类时,就会实例化一个 Car_Factory 实例(INSTANCE)

    __恶汉单例确保 INSTANCE 变量在多线程环境下状态的唯一性__。因为使用 @Inject 注解一个类的构造函数时,多个Component都可以 调用 Car_Factory 来注入依赖。即使这些 Component 处于不同线程,它们调用的都是同一个 Car_Factory 实例。

  2. 采用简单工厂模式,外部只需要调用Car_Factory#create() 接口,即可得到一个 Car_Factory 实例

  3. 获取 Car_Factory 实例后只需要调用 get 接口即可获取到一个 car 对象

Module 和 Provider 注解

当我们使用 @Module 和 @Provider 来提供依赖时,build 项目后,Dagger 会自动生成一个 FatherModule_ProvideCarFactory 类,源码如下:

public final class FatherModule_ProvideCarFactory implements Factory<Car> {
  private final FatherModule module;

  public FatherModule_ProvideCarFactory(FatherModule 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(FatherModule module) {
    return new FatherModule_ProvideCarFactory(module);
  }
}
  1. FatherModule_ProvideCarFactory 对象的实例化需要传入一个 module(FatherModule 对象)

  2. 当我们调用 FatherModule_ProvideCarFactory 对象的get方法时,其实调用的就是 module.provideCar() 方法

  3. 为什么 FatherModule_ProvideCarFactory 不做单例处理呢? 因为一个 module 对应一个 Component。FatherModule_ProvideCarFactory 对应的就是给 FatherComponent 来调用的。 不存在多个 Component 同时调用 FatherModule_ProvideCarFactory 的情况。

ps:

已在多个框架中看到采用 Preconditions.checkNotNull() 方法来做对象的判空处理,源码如下:

public final class Preconditions {
  /**
   * Ensures that an object reference passed as a parameter to the calling method is not null.
   *
   * @param reference an object reference
   * @return the non-null reference that was validated
   * @throws NullPointerException if {@code reference} is null
   */
  public static <T> T checkNotNull(T reference) {
    if (reference == null) {
      throw new NullPointerException();
    }
    return reference;
  }

  /**
   * Ensures that an object reference passed as a parameter to the calling method is not null.
   *
   * @param reference an object reference
   * @param errorMessage the exception message to use if the check fails
   * @return the non-null reference that was validated
   * @throws NullPointerException if {@code reference} is null
   */
  public static <T> T checkNotNull(T reference, String errorMessage) {
    if (reference == null) {
      throw new NullPointerException(errorMessage);
    }
    return reference;
  }

  private Preconditions() {}
}