Dagger2
关于Dagger2的一些基础概念(Inject
,Component
,Module
,Provides
)及注入原理,在网上也非常多关于这方面的文章,这里我就不多讲,这里推荐几篇文章,大家可以先仔细看看
Scope
Scope是Dagger2中的作用域,在上面的文章也详细的介绍了关于的它的作用,主要是
- 更好的管理Component之间的组织方式,不管是依赖方式还是包含方式,都有必要用自定义的Scope注解标注这些Component,这些注解最好不要一样了,不一样是为了能更好的体现出Component之间的组织方式。还有编译器检查有依赖关系或包含关系的Component,若发现有Component没有用自定义Scope注解标注,则会报错。
- 更好的管理Component与Module之间的匹配关系,编译器会检查 Component管理的Modules,若发现标注Component的自定义Scope注解与Modules中的标注创建类实例方法的注解不一样,就会报错。
- 可读性提高,如用Singleton标注全局类,这样让程序猿立马就能明白这类是全局单例类。
但是还有个很重要的作用上面的没有讲解到,那就是关于Scope可以实现局部单例
Scope实现局部单例
这里的示例我引用了Piasy关于Scope的文章中的例子,通过这个例子,我们可以得出以下结论:
- component 的 inject 函数不要声明基类参数;
- Scope 注解必须用在 module 的 provide 方法上,否则并不能达到局部单例的效果;
- 如果 module 的 provide 方法使用了 scope 注解,那么 component 就必须使用同一个注解,否则编译会失败;
- 如果 module 的 provide 方法没有使用 scope 注解,那么 component 和 module 是否加注解都无关紧要,可以通过编译,但是没有局部单例效果;
- 对于直接使用 @Inject 构造函数的依赖,如果把 scope 注解放到它的类上,而不是构造函数上,就能达到局部单例的效果了;
我们来测试下Module的Provider方法是否使用@ActivityScope
标注,apt给我们生成的源代码
DaggerDemoComponent.java
使用@ActivityScope
标注
|
|
不使用@ActivityScope
标注
|
|
可以看出他们得到Provider的方式是不一样的,使用@ActivityScope
注解的是通过ScopedProvider
拿到的,我们看下
ScopedProvider.java
|
|
看到这里想必大家已经明白,ScopedProvider返回给我们的是一个单例,这个单例是依赖于DemoComponent的,所以叫它局部单例。
其实从这点也能理解为什么叫它作用域的原因了,因为它的创建和销毁跟Component是息息相关的,也印证了上面提到管理作用