Code example
// 父类
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 generated code reading
The main analysis is how to generate a Map<Class<? extends Animal>, Animal> collection
Looking at the code generated by Degger2 based on the above case, the generated code is in the build\generated\sources\annotationProcessor\..
folder.
- Analyzing the injected logic, you can basically figure it out.
.inject(this)
The logic after calling the injection is as follows:
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);
}
}
At this point, the Map
collection is created, and the last step is to inject the object.
- Object injection
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;
}
}