目录
前置知识
这篇文章的内容会涉及以下前置 / 相关知识,贴心的我都帮你准备好了,请享用~
- APT 【点赞催更】
- Java | 注解(含 Kotlin)
1. 为什么要进行依赖注入
依赖注入(Dependency Injection,简称 DI)其实并不是一个很神秘的概念,往往在不经意地间我们就使用了依赖注入。依赖注入应用了 “控制反转(IoC)” 的原理,简单来说就是在类的外部构造依赖项,使用构造器或者 setter 注入。
提示: 你往往在不经意间使用了依赖注入的思想。
使用依赖注入可以为我们带来什么好处呢?
- 重用组件: 因为我们在类外部构造依赖项;
- 组件解耦: 当我们需要修改某个组件的实现时,不需要在项目中进行大量变更;
- 易测试: 我们可以向依赖方注入依赖项的模拟实现,这使得依赖方的测试更加容易;
- 生命周期透明: 依赖方不感知依赖项创建 / 销毁的生命周期,这些可以交给依赖注入框架管理。
2. Android 依赖注入框架
当只有一个依赖项时,手动进行依赖注入很简单,但随着项目规模变大,手动注入会变得越来越复杂。而使用依赖注入框架,可以让依赖注入的过程更加简便,另外,依赖注入框架往往还提供了管理依赖项的生命周期的功能。从实现上,依赖注入框架可以归为两类:
- 1、基于反射的动态方案: Guice、Dagger;
- 2、基于编译时注解的静态方案(性能更高): Dagger2、Hilt、ButterKnife。
提示:依赖注入框架本质上不是提供了依赖注入的能力,而是采用了注解等方式让依赖注入变得更加简易。
在这里面,Dagger2 和 Hilt 是我们今天讨论的主题。
-
Dagger2: Dagger 的名字取自有向无环图(DAG,Directed acyclic graph),最初由 Square 组织开发,而后来的 Dagger2 和 Hilt 框架则由 Square 和 Google 共同开发维护。
-
Hilt: Hilt 是 Dagger2 的二次封装,Hilt 本质上是对 Dagger 进行场景化。它为 Android 平台制定了一系列规则,大大简化了 Dagger2 的使用。在 Dagger2 里,你需要手动获取依赖图和执行注入操作,而在 Hilt 里,注入会自动完成,因为 Hilt 会自动找到 Android 系统组件中那些最佳的注入位置。
下面,我们分别来讨论 Dagger2 和 Hilt 两个框架。原本我不打算介绍太多 Dagger2 的内容(因为在 Android 里我们是直接使用 Hilt),考虑到两者的关系还是觉得还是有必要把 Dagger2 讲清楚,才能真正理解 Hilt 帮我们做了什么。
3. Dagger2 使用教程
提示: 我在学习 Dagger2 时,也阅读了很多文章和官方文档。有些作者会列举出所有注解的用法,有些作者只介绍用法而忽略解释自动生成的代码。我也在寻求一种易于理解 / 接受的讲法,最后我觉得先「基础注解」再「复杂注解」,边介绍用法边解释自动生成代码的方式,或许是更容易理解的方式。期待得到你的反馈~
在讨论的过程中,我们通过一个简单的例子来展开:假设我们有一个用户数据模块,它依赖于两个依赖项:
public class UserRepository {