(9) Dagger2 @Qualifier case analysis

Code example
class Tiger {
    
    
    String name;
    public Tiger(String name) {
    
    
        this.name = name;
    }
    public Tiger() {
    
    
    }
    public void sleep() {
    
    
        System.out.println("Tiger sleeping");
    }
}
// 自定义Qualifier注解
@Qualifier
public @interface Tiger1 {
    
    
}
// 自定义Qualifier注解
@Qualifier
public @interface Tiger2 {
    
    
}
@Module
class ZooModule {
    
    
    // 使用自定义Qualifier注解
    @Tiger1
    @Provides
    public Tiger providerTiger_1() {
    
    
        return new Tiger();
    }
    @Tiger2
    @Provides
    public Tiger providerTiger_2() {
    
    
        return new Tiger("米饭");
    }
}
@Component(modules = {
    
    ZooModule.class})
interface ZooComponent {
    
    
    Zoo inject(Zoo zoo);
}
public class Zoo {
    
    
    // 使用自定义Qualifier注解,用以区分tiger1到底使用注射器中的哪个对象.
    @Tiger1
    @Inject
    Tiger tiger1;
    @Tiger2
    @Inject
    Tiger tiger2;

    @Test
    public void 案例九() {
    
    
        DaggerZooComponent.create().inject(this);
        tiger1.sleep();
        tiger2.sleep();
    }
}
Dagger2 generated code reading

The main analysis is how to distinguish when there are two objects of the same type in the same syringe and the two objects need to be used in the container.

Looking at the code generated by Degger2 based on the above case, the generated code is in the build\generated\sources\annotationProcessor\..folder.

  • When called .inject(this), the final called code is as follows:
final class DaggerZooComponent implements ZooComponent {
    
    
   @Override
    public Zoo inject(Zoo zoo) {
    
    
        return injectZoo(zoo);
    }
   private Zoo injectZoo(Zoo instance) {
    
    
        // ZooModule_ProviderTiger_1Factory.providerTiger_1(zooModule): 通过ZooModule中的providerTiger_1()方法获取tiager对象
        // ZooModule_ProviderTiger_2Factory.providerTiger_2(zooModule): 通过ZooModule中的providerTiger_2()方法获取tiager对象
        Zoo_MembersInjector.injectTiger1(instance, ZooModule_ProviderTiger_1Factory.providerTiger_1(zooModule));
        Zoo_MembersInjector.injectTiger2(instance, ZooModule_ProviderTiger_2Factory.providerTiger_2(zooModule));
        return instance;
   } 
}

The above very conventional code, the only difference is that tigerwhen assigning objects to the fields in the container, two different methods are called respectively

public final class Zoo_MembersInjector implements MembersInjector<Zoo> {
    
    
    @InjectedFieldSignature("com.yey.dagger2.Zoo.tiger1")
    @Tiger1 // 这是案例中定义的注解
    public static void injectTiger1(Zoo instance, Object tiger1) {
    
    
      instance.tiger1 = (Tiger) tiger1;// 容器中tiger1字段赋值为providerTiger_1()返回的对象
    }
    @InjectedFieldSignature("com.yey.dagger2.Zoo.tiger2")
    @Tiger2
    public static void injectTiger2(Zoo instance, Object tiger2) {
    
    
      instance.tiger2 = (Tiger) tiger2;// 容器中tiger2字段赋值为providerTiger_2()返回的对象
    }
}

When there are multiple objects of the same type in the syringe, custom @Qualifierannotations can help the container to obtain a specific object.In addition, if there are multiple objects of the same type in the syringe, Dagger2 will report an error and repeated binding.

Guess you like

Origin blog.csdn.net/MoLiao2046/article/details/106884536