Dagger2 中的 Qualifier

Dagger2 中创建实例对象有两种方式:

  • Inject 维度:通过用 Inject 注解构造函数
  • Module 维度:通过工厂模式的 Module 创建

其中,Module 的优先级比 Inject 高。基于同样维度的不同实例,比如
@Inject A(){}@Inject A(B b){},系统就会抱错,这种情况叫做依赖注入迷失

Qualifier限定符 就是解决依赖注入迷失的。

1.定义限定符注解

  • java 中的方式:

    1
    2
    3
    4
    5
    6
    @Qualifier
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Named {
    String name() default "";
    }
  • kotlin 中的方式:

    1
    2
    3
    4
    @Qualifier
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    annotation class Named(val name: String)

2.Module 中使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Provides
@Named("dog")
@Singleton
fun providesAnimal(): Dog {
Log.e("abc", "----- dog -----")
return Dog()
}


@Provides
@Named("dog2")
@Singleton
fun providesAnimal2(): Dog {
Log.e("abc", "----- dog2 -----")
return Dog()
}

3.实例化

1
2
3
4
5
6
7
@Inject
@field:Named("dog")
lateinit var dog: Dog

@Inject
@field:Named("dog2")
lateinit var dog2: Dog

根据打印的内容可以知道,创建对象 dog 和 dog2 的时候分别调用了 providesAnimal() 和 providesAnimal2()。
说明:如果用@Named("xx")代替@field:Named("xx")会报错,因为代码编译为 Java 字节码的时候会对应三个目标元素:一个是变量本身、还有 getter 和 setter,Kotlin 不知道这个变量的注解应该使用到哪个目标上。使用 field 关键字是告诉 Kotlin 所注解的目标是哪个。


最后
项目源码


其他几篇的链接:
Dagger2 中的 SubComponent
Dagger2 中的 Scope、dependencies
Dagger2 中使用 AndroidInjection 优化注入流程
Dagger2 中的 Binds、IntoSet、IntoMap