(五) Dagger2 @Module分析三

代碼示例
class Food {
}
class Tiger {
    // 假如老虎需要食物
    Food food;
    public Tiger(Food food) {
        this.food = food;
    }
    public void sleep() {
        System.out.println("Tiger sleeping");
    }
}
// 爲注射器提供工廠類
@Module
class FoodModule {
    @Provides
    public Food providerFood() {
        return new Food();
    }
}
// 爲注射器提供工廠類
// @Module: 表示Dagger2可以將該類當作對象工廠.
@Module
class ZooModule {
    // @Provides: 表示Dagger2可以調用providerTiger(Food food)方法爲注射器提供對象.
    @Provides
    public Tiger providerTiger(Food food) {
        return new Tiger(food);
    }
}
// 對象使用者
public class Zoo {
    // @Inject: 該註解用於成員變量上代表注射器可以爲該成員變量賦值對象.
    @Inject
    Tiger tiger;

    @Test
    public void 案例五() {
        DaggerZooComponent.create().inject(this);
        tiger.sleep();
    }
}
// 注射器
// @Component: 該註解是用來創造對象提供方和對象使用間的橋樑,如何將對象賦值給成員變量都是由它來做的.
// (modules = {ZooModule.class,FoodModule.class}): 表示該注射器可以使用ZooModule,FoodModule對象工廠提供方法.
@Component(modules = {ZooModule.class,FoodModule.class})
interface ZooComponent {
    Zoo inject(Zoo zoo);
}
Dagger2生成代碼閱讀

主要分析不同Module中的方法產生了依賴關係,將兩個Module加入同一個注射器中,注射器會根據對象使用者的需求來自動處理兩個Module間的依賴關係.

就着上面的案例來看下Degger2生成的代碼,生成的代碼在build\generated\sources\annotationProcessor\..文件夾中.

  1. DaggerZooComponent.create()
    create()用來生成DaggerZooComponent對象,DaggerZooComponent的父類是ZooComponent接口,它重寫了接口中的inject()方法.
final class DaggerZooComponent implements ZooComponent {
    // 兩個工廠對象
    private final FoodModule foodModule; 
    private final ZooModule zooModule;
    // 由Builder.build()創建DaggerZooComponent對象.
    private DaggerZooComponent(ZooModule zooModuleParam, FoodModule foodModuleParam) {
      this.foodModule = foodModuleParam;
      this.zooModule = zooModuleParam;
    }
    // create()方法創建DaggerZooComponent()對象
    public static ZooComponent create() {
      return new Builder().build();
    }
    static final class Builder {
        private ZooModule zooModule;
        private Builder() {
        }
        // build()方法返回DaggerZooComponent對象.  
        public ZooComponent build() {
            // 如果zooModule爲null,那麼就創建該對象.ZooModule代表工廠.
            if (zooModule == null) {
              this.zooModule = new ZooModule();
            }
            // 如果FoodModule爲null,那麼就創建該對象.FoodModule代表工廠.
            if (foodModule == null) {
              this.foodModule = new FoodModule();
            }
            // 將ZooModule,FoodModule存儲在DaggerZooComponent對象中
            return new DaggerZooComponent(zooModule, foodModule);
        }
    }
}
  1. .inject(this)對象注入
    使用DaggerZooComponent對象將Dagger2創建的Tiger對象注入到Zoo中.
final class DaggerZooComponent implements ZooComponent {
    // 接口中的方法,由DaggerZooComponent實現,該方法就是用來向Zoo對象中注入Tiger對象的.
    @Override
    public Zoo inject(Zoo zoo) {
        // zoo就是inject(this)中的this了,代表Zoo對象.
        return injectZoo(zoo);
    }
    private Zoo injectZoo(Zoo instance) {
        // 1. getTiger(): 通過ZooModule工廠獲取Zoo需要的Tiger對象.
        // 2. Zoo_MembersInjector.injectTiger(instance, getTiger()): 這裏就是爲Zoo對象中所需字段賦值.
        Zoo_MembersInjector.injectTiger(instance, getTiger());
        return instance;
    }
}
  1. getTiger()獲取Tiger對象。
final class DaggerZooComponent implements ZooComponent {
        private final ZooModule zooModule;// 提供對象的工廠
        private DaggerZooComponent(ZooModule zooModuleParam) {
            this.zooModule = zooModuleParam;
        }
        private Tiger getTiger() {
            // 接着向下看
            // zooModule:提供對象的工廠
            // new Food(): 因爲Food類的構造方法中標註了@Inject。
            // 從這裏可以看出,只要將Module或者對象加入到注射器中,Module和對象間的依賴注射器都會自動處理好。
            return ZooModule_ProviderTigerFactory.providerTiger(zooModule, new Food());
        } 
    private Tiger getTiger() {
        // 由foodModule獲取food對象
        Food food = FoodModule_ProviderFoodFactory.providerFood(foodModule);
        // 由zooModule獲取tiger對象
        Tiger tiger = ZooModule_ProviderTigerFactory.providerTiger(zooModule, food);
        return tiger;
    }
}
public final class FoodModule_ProviderFoodFactory implements Factory<Food> {
    public static Food providerFood(FoodModule instance) {
        // instance: 爲FoodModule類,它的providerFood()作用是返回food對象。
        return Preconditions.checkNotNull(instance.providerFood(), "Cannot return null from a non-@Nullable @Provides method");
    }
}
public final class ZooModule_ProviderTigerFactory implements Factory<Tiger> {
    public static Tiger providerTiger(ZooModule instance, Object food) {
        // instance: 爲ZooModule類,它的providerTiger(Food food)作用是返回Tiger對象。
        // food對象: 爲上一步中由FoodModule_ProviderFoodFactory.providerFood(foodModule)方法獲取到的。
        return Preconditions.checkNotNull(instance.providerTiger((Food) food), "Cannot return null from a non-@Nullable @Provides method");
    }
}
  1. Zoo_MembersInjector.injectTiger(instance, getTiger())
    該方法爲Zoo對象中所需字段賦值,instanceZoo對象,getTiger()創建tiger對象。
public final class Zoo_MembersInjector implements MembersInjector<Zoo> {
    @InjectedFieldSignature("com.yey.dagger2.Zoo.tiger")
    public static void injectTiger(Zoo instance, Object tiger) {
        // 此處就是爲zoo.tiger字段賦值的操作.
        instance.tiger = (Tiger) tiger;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章