代碼示例
// 父類
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;
}
}