1
1
2
- - [ 1. 依赖注入 : Dependency Injection,DI] ( #1- 依赖注入--dependency-injectiondi )
3
- - [ 1.1. 什么是依赖?] ( #11- 什么是依赖 )
4
- - [ 1.2. 依赖存在的问题] ( #12- 依赖存在的问题 )
5
- - [ 1.3. 什么是依赖注入] ( #13- 什么是依赖注入 )
6
- - [ 1.4. Dagger] ( #14- dagger )
7
- - [ 1.4.1. 基本实现概述] ( #141- 基本实现概述 )
8
- - [ 1.4.2. 其他特性] ( #142- 其他特性 )
9
- - [ 1.5. Koin] ( #15- koin )
10
- - [ 2. Dagger] ( #2- dagger )
11
- - [ 2. 1. Dagger 基础] ( #21 -dagger-基础 )
12
- - [ 2. 1.1. @Inject ] ( #211 -inject )
13
- - [ 2. 1.1.1. 声明在成员变量上] ( #2111 -声明在成员变量上 )
14
- - [ 2. 1.1.2. 声明在构造函数上] ( #2112 -声明在构造函数上 )
15
- - [ 2. 1.2. @Module ] ( #212 -module )
16
- - [ 2. 1.3. @Component ] ( #213 -component )
17
- - [ 2. 1.3.1. 暴露依赖实例] ( #2131 -暴露依赖实例 )
18
- - [ 2. 1.4. Dagger的简单使用] ( #214 -dagger的简单使用 )
19
- - [ 2. 1.5. @Binds ] ( #215 -binds )
20
- - [ 2. 1.6. Component依赖] ( #216 -component依赖 )
21
- - [ 2. 1.7. Subcomponent] ( #217 -subcomponent )
22
- - [ 2. 1.8. @Scope ] ( #218 -scope )
23
- - [ 2. 1.8.1. 单例的实现原理] ( #2181 -单例的实现原理 )
24
- - [ 2. 1.9. @Named ] ( #219 -named )
25
- - [ 2.1.10. Dagger in Android] ( #2110 -dagger-in-android )
26
- - [ 2.1.11. Activity的自动注入] ( #2111 -activity的自动注入 )
27
- - [ 2.1.12. Activity自动注入实现原理] ( #2112 -activity自动注入实现原理 )
28
- - [ 3 . 参考文档] ( #3 -参考文档 )
29
-
30
-
31
- # 1. 依赖注入 : Dependency Injection,DI
32
-
33
- ## 1.1. 什么是依赖?
2
+ - [ 依赖注入 : Dependency Injection,DI] ( #依赖注入--dependency-injectiondi )
3
+ - [ 什么是依赖?] ( #什么是依赖 )
4
+ - [ 依赖存在的问题] ( #依赖存在的问题 )
5
+ - [ 什么是依赖注入] ( #什么是依赖注入 )
6
+ - [ Dagger] ( #dagger )
7
+ - [ 基本实现概述] ( #基本实现概述 )
8
+ - [ 其他特性] ( #其他特性 )
9
+ - [ Koin] ( #koin )
10
+ - [ Dagger] ( #dagger-1 )
11
+ - [ 1. Dagger 基础] ( #1 -dagger-基础 )
12
+ - [ 1.1. @Inject ] ( #11 -inject )
13
+ - [ 1.1.1. 声明在成员变量上] ( #111 -声明在成员变量上 )
14
+ - [ 1.1.2. 声明在构造函数上] ( #112 -声明在构造函数上 )
15
+ - [ 1.2. @Module ] ( #12 -module )
16
+ - [ 1.3. @Component ] ( #13 -component )
17
+ - [ 1.3.1. 暴露依赖实例] ( #131 -暴露依赖实例 )
18
+ - [ 1.4. Dagger的简单使用] ( #14 -dagger的简单使用 )
19
+ - [ 1.5. @Binds ] ( #15 -binds )
20
+ - [ 1.6. Component依赖] ( #16 -component依赖 )
21
+ - [ 1.7. Subcomponent] ( #17 -subcomponent )
22
+ - [ 1.8. @Scope ] ( #18 -scope )
23
+ - [ 1.8.1. 单例的实现原理] ( #181 -单例的实现原理 )
24
+ - [ 1.9 @Named ] ( #19 -named )
25
+ - [ 2. Dagger in Android] ( #2 -dagger-in-android )
26
+ - [ 2.1. Activity的自动注入] ( #21 -activity的自动注入 )
27
+ - [ 2.2. Activity自动注入实现原理] ( #22 -activity自动注入实现原理 )
28
+ - [ 4 . 参考文档] ( #4 -参考文档 )
29
+
30
+
31
+ # 依赖注入 : Dependency Injection,DI
32
+
33
+ ## 什么是依赖?
34
34
35
35
比如类` ClassroomActivity ` 中用到了` Teacher ` 类的实例:
36
36
@@ -42,13 +42,13 @@ class ClassroomActivity {
42
42
43
43
这里` Teacher ` 就被称为` ClassroomActivity ` 的依赖
44
44
45
- ## 1.2. 依赖存在的问题
45
+ ## 依赖存在的问题
46
46
47
47
想象我们程序中有多个地方需要` Teacher ` 对象,那就要在很多地方手动构造` Teacher ` , 万一` Teacher ` 的构造方式发生了变化, 那你就要改动多处来实现` Teacher ` 新的构造方式
48
48
49
49
导致上面这个问题的原因是 : ** 依赖的创建方式与使用方耦合与业务逻辑** , ` 依赖注入(DI) ` 就是为了解决这个问题
50
50
51
- ## 1.3. 什么是依赖注入
51
+ ## 什么是依赖注入
52
52
53
53
依赖注入是这样的一种行为,在类` ClassroomActivity ` 中不主动创建` Teacher ` 的对象,而是通过外部传入` Teacher ` 对象形式来设置依赖, 即** 非自己主动初始化依赖(对象),而是通过外部传入依赖的方式**
54
54
@@ -66,9 +66,9 @@ class ClassroomActivity {
66
66
67
67
目前` Android ` 中有许多` 依赖注入(DI) ` 框架, ** 本文主要介绍一下` Dagger ` 和` Koin ` ,了解一下它们的实现原理**
68
68
69
- ## 1.4. Dagger
69
+ ## Dagger
70
70
71
- ### 1.4.1. 基本实现概述
71
+ ### 基本实现概述
72
72
73
73
` Dagger ` 的核心实现原理是:** 基于注解在编译期产生依赖注入相关代码,然后开发者调用生成的代码进行依赖注入** , 以一个简单的使用场景为例:
74
74
@@ -116,7 +116,7 @@ ClassroomActivity_MembersInjector.(activity, ClassroomModule_ProvideTeacherFacto
116
116
117
117
即` Dagger ` 会生成** 依赖实例构造的工厂方法** 和** 依赖注入相关模板方法**
118
118
119
- ### 1.4.2. 其他特性
119
+ ### 其他特性
120
120
121
121
除了基本的依赖注入外` Dagger ` 还支持 :
122
122
@@ -125,7 +125,7 @@ ClassroomActivity_MembersInjector.(activity, ClassroomModule_ProvideTeacherFacto
125
125
126
126
` Dagger ` 有完善、强大的依赖注入功能,不过` Dagger ` 的学习难度比较高,不是那么容易上手, 而` Koin ` 相较于` Dagger ` 在上手程度上则容易的多:
127
127
128
- ## 1.5. Koin
128
+ ## Koin
129
129
130
130
` Koin ` 是为` Kotlin ` 开发者提供的一个实用型轻量级依赖注入框架,采用纯` Kotlin ` 语言编写而成,仅使用功能解析,无代理、无代码生成、无反射,它的实现依赖于` kotlin ` 强大的语法糖(例如 Inline、Reified 等等)和函数式编程。
131
131
@@ -192,15 +192,15 @@ internal fun <T> resolveInstance(indexKey: IndexKey, parameters: ParametersDefin
192
192
193
193
dagger的语法比较复杂, 下面就简单学习和理解一下` dagger ` 中的各种用法:
194
194
195
- # 2. Dagger
195
+ # Dagger
196
196
197
- ## 2. 1. Dagger 基础
197
+ ## 1. Dagger 基础
198
198
199
- ### 2. 1.1. @Inject
199
+ ### 1.1. @Inject
200
200
201
201
它既可以用来指明对象的依赖,也可以用来指明依赖对象的创建方式, 不同的用法` Dagger ` 会在编译期生成不同的辅助类来完成依赖实例的注入 :
202
202
203
- #### 2. 1.1.1. 声明在成员变量上
203
+ #### 1.1.1. 声明在成员变量上
204
204
205
205
```
206
206
class StudentTest {
@@ -235,7 +235,7 @@ public final class StudentTest_MembersInjector implements MembersInjector<Studen
235
235
236
236
> ` Provider<NameInfo> ` 创建` NameInfo ` 的模板接口
237
237
238
- #### 2. 1.1.2. 声明在构造函数上
238
+ #### 1.1.2. 声明在构造函数上
239
239
240
240
```
241
241
class Student @Inject constructor(val nameInfo: NameInfo) : IPeople
@@ -261,7 +261,7 @@ public final class Student_Factory implements Factory<Student> {
261
261
262
262
> 如果构造参数上标记了` @Inject ` ,那么` Dagger ` 会先寻找这个参数的` XX_Factory ` ,创建这个参数对象,然后再创建目前对象
263
263
264
- ### 2. 1.2. @Module
264
+ ### 1.2. @Module
265
265
266
266
它用来封装创建对象实例的方法:
267
267
@@ -292,7 +292,7 @@ public final class StudentModule_ProvideNameInfoFactory implements Factory<NameI
292
292
293
293
即通过` StudentModule().provideNameInfo() ` 创建对应的` NameInfo ` 实例。
294
294
295
- ### 2. 1.3. @Component
295
+ ### 1.3. @Component
296
296
297
297
管理依赖实例, 链接` @Inject ` 和` @Module ` , 可以为对象注入依赖实例 :
298
298
@@ -338,7 +338,7 @@ public final class DaggerStudentComponent implements StudentComponent {
338
338
339
339
> ` DaggerStudentComponent ` 私有化构造函数,通过` Builder ` 来创建, 创建时需要传入` StudentModule ` 对象
340
340
341
- #### 2. 1.3.1. 暴露依赖实例
341
+ #### 1.3.1. 暴露依赖实例
342
342
343
343
可以在` @Component ` 添加方法来暴露依赖实例:
344
344
@@ -356,7 +356,7 @@ interface ClassroomComponent {
356
356
val teacher = DaggerClassroomComponent.builder().classroomModule(ClassroomModule()).build().getTeacher()
357
357
```
358
358
359
- ### 2. 1.4. Dagger的简单使用
359
+ ### 1.4. Dagger的简单使用
360
360
361
361
通过对上面三大金刚的介绍, 我们了解了` Dagger ` 的基本使用与实现原理, 在编码时就可以这样使用:
362
362
@@ -378,7 +378,7 @@ logcat输出:
378
378
D/dagger-test: wang pengcheng
379
379
```
380
380
381
- ### 2. 1.5. @Binds
381
+ ### 1.5. @Binds
382
382
383
383
它也可以像` @Provides ` 指明一个依赖实例的提供方式, 不过它只能声明在抽象方法上, 它用来告诉` Dagger ` 接口应采用哪种实现:
384
384
@@ -407,7 +407,7 @@ class Student @Inject constructor(val nameInfo: NameInfo) : IPeople
407
407
fun providePeopleWithStudent() = Student(provideNameInfo()) as IPeople
408
408
```
409
409
410
- ### 2. 1.6. Component依赖
410
+ ### 1.6. Component依赖
411
411
412
412
如果` ClassroomComponent ` 需要使用` StudentComponent ` 的依赖实例, 则可以这样写:
413
413
@@ -460,7 +460,7 @@ class ClassroomTest {
460
460
}
461
461
```
462
462
463
- ### 2. 1.7. Subcomponent
463
+ ### 1.7. Subcomponent
464
464
465
465
> 上面` dependencies = [XXXComponent::class] ` 可以简单的理解为: ** ` AComponent ` 把` BComponent ` 变成成员变量, 然后使用` BComponent ` 其依赖注入的能力**
466
466
@@ -554,7 +554,7 @@ class StudentTest {
554
554
}
555
555
```
556
556
557
- ### 2. 1.8. @Scope
557
+ ### 1.8. @Scope
558
558
559
559
` @Scope ` 在` Dagger ` 中和` @Component ` 紧紧相连 : ** 如果一个` @Module ` 提供的依赖实例声明了和` @Component ` 相同的` @Scope ` ,那么这个` @Component ` 会使用同一个依赖实例来做依赖注入** :
560
560
@@ -592,7 +592,7 @@ class Test {
592
592
593
593
上面这个` Test ` 的两个成员变量其实引用的是同一个` Classroom ` 实例, 不过在使用` @Scope ` 是需要注意 : ** ` @Subcomponent ` 不能和` @Component ` 声明相同的` @Scope ` **
594
594
595
- #### 2. 1.8.1. 单例的实现原理
595
+ #### 1.8.1. 单例的实现原理
596
596
597
597
其实看一下` Component ` 的注入实现就明白了:
598
598
@@ -606,7 +606,7 @@ private ClassroomActivity injectClassroomActivity(ClassroomActivity instance) {
606
606
607
607
即使用同一个` Provider<T> ` 来获取的对象
608
608
609
- ### 2. 1.9. @Named
609
+ ### 1.9 @Named
610
610
611
611
在` Dagger ` 中提供依赖实例的方式一种有两种 :
612
612
@@ -638,7 +638,7 @@ class ClassroomActivity : Activity() {
638
638
```
639
639
640
640
641
- ### 2.1.10. Dagger in Android
641
+ ### 2. Dagger in Android
642
642
643
643
上面介绍了` Dagger ` 的基本原理与使用方法, 不过在Android中如何使用` Dagger ` 呢?
644
644
@@ -662,7 +662,7 @@ class ClassroomActivity : Activity() {
662
662
663
663
怎么解决呢?` Dagger ` 官方给出的实现步骤如下:
664
664
665
- ### 2.1.11. Activity的自动注入
665
+ ### 2.1. Activity的自动注入
666
666
667
667
1 . 顶层Component绑定AndroidInjectionModule
668
668
@@ -757,7 +757,7 @@ abstract class ClassroomActivityModule {
757
757
758
758
那上面实现原理是什么呢?
759
759
760
- ### 2.1.12 . Activity自动注入实现原理
760
+ ### 2.2 . Activity自动注入实现原理
761
761
762
762
来看一下` DaggerAppComponent ` 中生成的依赖注入代码:
763
763
@@ -831,7 +831,9 @@ public boolean maybeInject(T instance) {
831
831
832
832
其实上面` injectorFactories ` 就是` DaggerAppComponent ` 中的那个` Factory Map ` , 最终调用到` ClassroomActivitySubcomponentImpl.inject() `
833
833
834
- # 3. 参考文档
834
+
835
+
836
+ # 4. 参考文档
835
837
836
838
[ google dagger] ( https://developer.android.com/training/dependency-injection/dagger-android )
837
839
0 commit comments