前言
Dagger 是一个优秀的依赖注入框架,特别是在 Android 开发中,有大量的项目在使用。本文用了一个形象的例子,用大量的篇幅来讲解这个库,因为文章过长,因此分为四个部分,请大家按照顺序来看,本文是这个系列的第四章,也就是最后一篇了:
- 这可能是本年度最好用的 Dagger 使用教程 一(基本使用)
- 这可能是本年度最好用的 Dagger 使用教程 二(限定注解 @Named、@Qulifier 和 范围注解 @Singleton、@Scope)
- 这可能是本年度最好用的 Dagger 使用教程 三(依赖注入器的依赖、子组件、Lazy、Provider)
- 这可能是本年度最好用的 Dagger 使用教程 四(使用 @Builder 和 @Factory 创建依赖注入器)
另外,这个是我的微信公众号,也是最近在做,希望大家能够多多关注,我会不定期更新优秀的技术文章:
接下来,开始我们的正文吧
在前面的例子中,我们吐槽了在默认情况下,Dagger 生成的代码会有一些方法名不怎么好看,例如上面的 cPUProvider
、uPSExpress
这种。那么有人就说了,这个地方能不能改得更好看一点呢?答案肯定是可以的。
这就要介绍 @Component
注解中的另外两个注解了: @Component.Builder
和 @Subcomponent.Factory
。通过这两个注解,我们可以对 Dagger 生成 Component
的实现类有一定的控制。
当我们创建一个类时,常用的设计模式就是 Builder 构造器模式和 Factory 工厂模式,其实这两个就对应了上述的两个注解。这里我们一个一个说,先说更为常用的 @Component.Builder
,然后再介绍 @Subcomponent.Factory
。
@Component.Builder
在我们不往 Component
接口中添加 Builder
或 Factory
时,Dagger 模式使用的就是这种构造器模式,但是咱们仍然可以使用这个注解,对生成代码的过程进行一些控制。
这里我们就修改一下 ZTOExpress
这个类,为其添加一个 Builder
:
@SanScope
@Component(modules = {TaoBao.class}, dependencies = UPSExpress.class)
public interface ZTOExpress {
void deliverTo(Person person);
ZTOShanghaiExpress.Factory getShanghaiDepartmentFactory();
@Component.Builder
interface Builder {
Builder setTaoBao(TaoBao taoBao);
Builder setUPSExpress(UPSExpress upsExpress);
ZTOExpress build();
}
}
很简单,在 ZTOExpress
中再添加一个 Builder
并使用 @Component.Builder
标注,而 Builder
里面的内容,就是很普通的构造器模式,咱们可以在里面修改代码。
在添加了这段代码后,只需要调用我们自己定义的 set
方法构造 ZTOExpress
然后再使用就行。这里就不演示了。
@Component.Factory
除了使用 Builder
模式,Dagger 还支持 Factory
工厂模式,其使用方式也跟上面的 Builder
类似。但是有一点需要注意的是,同一个 Component
是不能即添加 Builder
也添加 Factory 的。
由于上面已经给 ZTOExpress
添加了 Builder
,那我们现在就给 UPSExpress
添加 Factory
注解:
@Component(modules = CPUProvider.class)
public interface UPSExpress {
@Named("AMD") CPU getAMDCPU();
@Named("Intel") CPU getIntelCPU();
@Component.Factory
interface Factory {
UPSExpress create(CPUProvider cpuProvider);
}
}
在使用了工厂模式之后,我们再构造 UPSExpress
就得用如下的方式:
UPSExpress upsExpress = DaggerUPSExpress.factory().create(new CPUProvider());
@Subcomponent.Builder 和 @Subcomponent.Factory
不仅仅是依赖注入器可以添加构造器模式或工厂模式,子组件也可以使用构造器模式或工厂模式。只不是使用的是 @Subcomponent.Builder
和 @Subcomponent.Factory
。
例如,我们给中通的上海分部添加一个 Factory
:
@Subcomponent
public interface ZTOShanghaiExpress {
void deliverTo(Person person);
@Subcomponent.Factory
interface Factory {
ZTOShanghaiExpress create();
}
}
在使用时,由于子组件是要放到主组件中的,在这么写之后,就需要修改获取子组件的方式:
ZTOShanghaiExpress.Factory getShanghaiDepartmentFactory();
如果是添加了 @Subcomponent.Builder,那就改成下面的这样:
ZTOShanghaiExpress.Builder getShanghaiDepartmentFactory();
最后
Dagger 是一个优秀的依赖注入框架,特别是在 Android 开发中,有大量的项目在使用。本文用了大量的篇幅来讲解这个库,但是也只是涉及到了这个库的一小部分而已,仍然有大量的注解还没有讲到,例如 @Binds
、@BindsInstance
、@IntoMap
、@ClassKey
、@AssistedInject
、@Assisted
、@AssistedFactory
、@StringKey
等等。
Dagger 库内容庞大,若是想要全部弄明白这个库的所有功能,光凭一篇文章是不可能的。但是作为基本使用,本篇文章是值得一看的。在了解了本文内容之后,再碰到 Dagger 中的其他注解,学起来也不会很困难。
最后,祝各位大佬身体健康,升职加薪,愿我们的技术人生没有35岁危机。