(十二) Dagger2 @IntoMap案例分析

代碼示例
// 父類
abstract class Animal {
    // 抽象方法
    abstract void sleep();
}
// 子類
class Tiger extends Animal {
    @Inject
    public Tiger() {
    }
    @Override
    public void sleep() {
        System.out.println("Tiger sleeping");
    }
}
// 子類
class Cat extends Animal {
    // 將Cat對象加入注射器中
    @Inject
    public Cat() {
    }
    @Override
    public void sleep() {
        System.out.println("Cat sleeping");
    }
}
@Module
abstract class ZooModule {
    @IntoMap // 該註解的意思是將Animal對象注入Map集合中
    @AnimalKey(Tiger.class) // 以Tiger.class對象作爲key
    @Binds // 該註解可以視爲@Provides
    abstract Animal providerTiger(Tiger tiger);
    @IntoMap
    @AnimalKey(Cat.class)

    @Binds
    abstract Animal providerCat(Cat cat);
}
@Component(modules = {ZooModule.class})
interface ZooComponent {
    void inject(Zoo zoo);
}
public class Zoo {
    @Inject
    Map<Class<? extends Animal>, Animal> map;
    @Test
    public void 案例十() {
        DaggerZooComponent.create().inject(this);
        map.forEach(new BiConsumer<Class<? extends Animal>, Animal>() {
            @Override
            public void accept(Class<? extends Animal> aClass, Animal animal) {
                System.out.println(aClass);
                animal.sleep();
            }
        });
    }
}
Dagger2生成代碼閱讀

主要分析如何生成一個Map<Class<? extends Animal>, Animal>集合

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

  • 分析下注入的邏輯,基本就能弄清楚.調用.inject(this)注入後的邏輯如下:
final class DaggerZooComponent implements ZooComponent {
    @Override
    public void inject(Zoo zoo) {
      injectZoo(zoo);
    }
    private Zoo injectZoo(Zoo instance) {
        // getMapOfClassOfAndAnimal() :該方法生成一個Map集合
        Zoo_MembersInjector.injectMap(instance, getMapOfClassOfAndAnimal());
        return instance;
    }
    private Map<Class<? extends Animal>, Animal> getMapOfClassOfAndAnimal() {
        // 這裏很@IntoSet註解那段太像了.
        // 下面分析下如何創建一個Map集合
        return MapBuilder.<Class<? extends Animal>, Animal>newMapBuilder(2).put(Tiger.class, new Tiger()).put(Cat.class, new Cat()).build();
    }
}
  • MapBuilder.<Class<? extends Animal>, Animal>newMapBuilder(2)
public final class MapBuilder<K, V> {
    public static <K, V> MapBuilder<K, V> newMapBuilder(int size) {
      return new MapBuilder<>(size);
    }
    private MapBuilder(int size) {
      // 創建了一個LinkedHashMap
      contributions = newLinkedHashMapWithExpectedSize(size);
    }
}
  • .put(Tiger.class, new Tiger())
public MapBuilder<K, V> put(K key, V value) {
  // 將key與value添加到LinkedHashMap
  contributions.put(key, value);
  return this;
}
  • .build()
public Map<K, V> build() {
  switch (contributions.size()) {
    case 0:
      return Collections.emptyMap();
    default:
      // 將contributions返回  
      return Collections.unmodifiableMap(contributions);
  }
}

至此,Map集合就創建完成了,就剩下最後一步注入對象了.

  • 對象注入injectZoo(Zoo instance)
final class DaggerZooComponent implements ZooComponent {
   private Zoo injectZoo(Zoo instance) {
     // 爲Zoo對象中的字段賦值在這裏
     Zoo_MembersInjector.injectMap(instance, getMapOfClassOfAndAnimal());
     return instance;
   } 
}
public final class Zoo_MembersInjector implements MembersInjector<Zoo> {
    public static void injectMap(Zoo instance, Map<Class<? extends Animal>, Animal> map) {
      // 最終的賦值操作.  
      instance.map = map;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章