本文介绍了Dagger 2 中@Qualifier和@Named注解以及Lazy和Provider的使用。
《卜算子·咏梅》
风雨送春归,飞雪迎春到。已是悬崖百丈冰,犹有花枝俏。
俏也不争春,只把春来报。待到山花烂漫时,她在丛中笑。
-近代,毛泽东
Dagger 2 在 Android 上的使用(一)
Dagger 2 在 Android 上的使用(二)
Dagger 2 在 Android 上的使用(三)
Dagger 2 在 Android 上的使用(四)
Dagger 2 在 Android 上的使用(五)
注解@Qualifier和注解@Named
书接上文,在上文中我们使用注解@Binds
完成了对People抽象类的其中一个子类的绑定,如果我们想同时注入两个子类该怎样处理?1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27public abstract class People {
abstract String doWhat();
}
public class Student extends People {
@Inject
public Student() {
}
@Override
String doWhat() {
return "study";
}
}
public class Worker extends People {
@Inject
public Worker() {
}
@Override
String doWhat() {
return "work";
}
}
在Module类中添加对另一个子类Worker的绑定方法,这里我们用到了限定符注解@Named
,由于我们提供了多个依赖导致Dagger2无法识别要注入哪一个依赖,使用限定符注解@Named
很好地解决了这种问题。
1 | @Module |
在提供的实例添加注解@Named
,在使用依赖注入的地方添加同样的注解:
1 | public class PeopleActivity extends Activity { |
同样我们也可以使用限定符注解@Qualifier
通过自定义注解完成相同的功能。
使用注解@Qualifier
自定义注解:
1 | @Qualifier |
然后将自定义的注解替换上面注解@Named
:
1 | @Module |
由于使用注解@Named
需要指定字符串,可能会由于人为疏忽造成错误,所以这里推荐使用限定符注解@Qualifier
自定义注解的方法。
Lazy和Provider
我们可以使用Lazy
在注入时不进行初始化,在调用get方法时再初始化实例:
1 | public class PeopleActivity extends Activity { |
然后来看一下生成的代码:
1 | public final class DaggerPeopleComponent implements PeopleComponent { |
这里终于用到了生成的工厂类:
1 | public final class Worker_Factory implements Factory<Worker> { |
这里使用双重检查锁定为我们提供了唯一的实例,分析具体可参见:Java实现单例模式的正确姿势
1 | /** |
相对于Lazy
注入,Provider
注入每次调用get时都会提供一个新的实例,Provider
是由Java提供的接口:
1 | public class PeopleActivity extends Activity { |
打印输出如下:
1 | 2018-11-12 21:26:26.365 30805-30805/? D/debug: 1io.github.yuweiguocn.test.Student@205713d |
对比下生成的代码,唯一的区别就是Lazy使用DoubleCheck保证了实例的唯一性:
1 | public final class DaggerPeopleComponent implements PeopleComponent { |
总结
- 当提供多个相同类型的注入依赖时,可以使用限定符注解
@Qualifier
和注解@Named
,为了避免人为疏忽导致错误,推荐使用注解@Qualifier
自定义注解完成相应功能 - 使用Lazy可以在调用get方法时再初始化,其中使用了双重检查锁定保证了实例的唯一性
- 使用Provider在调用get方法时会提供新的实例
参考
- https://google.github.io/dagger/
- https://www.jianshu.com/p/24af4c102f62
- http://www.cnblogs.com/tiantianbyconan/p/5092083.html