(九) Dagger2 @Qualifier案例分析

代碼示例
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生成代碼閱讀

主要分析當同一個注射器中存在兩個相同類型的對象,容器中需要使用這兩個對象的時候該如何區分.

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

  • 當調用.inject(this)時,最終調用的代碼如下:
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;
   } 
}

上面的很常規的代碼,唯一的區別在於爲容器中字段賦值tiger對象時,分別調用了兩個不同的方法

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()返回的對象
    }
}

當注射器中存在多個相同類型對象時候,自定義@Qualifier註解能夠幫助容器獲取特定的對象,另外如果注射器中存在多個相同類型的對象,Dagger2會報錯重複綁定.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章