1.Dagger2.38.1源码解析-前言
发布于 2022年 04月 05日 10:09
前言
Dagger基于2.38.1的源码我给扣下来了,github地址
- 就凭我这份闲的蛋...呸呸!!!这份努力我也要个star,不给就哭!!!
主要分析的是ComponentProcessor类,该类也是Dagger核心。
本段代码基于2.38.1,代码和应用包都是基于该版本抠出来的。
代码相对于2.16有了很大的改进(2.16那就不是给人看的),但是还存在不足,尤其是component代码生成那一块还存在很大的改进控件。
Dagger本身也是使用注解,例如ComponenntProcessor类几个Inject修饰的变量的初始化就存在大量的注解,但是这里只是为了加深对Dagger注解实现的理解,代码的生成并不是自动生成的,而是"写"出来的。
如何写出来的? 答:对ComponentProcessor及需要的类gradle Dagger2.38.1。不是本章主题,不影响后面的学习。
ComponentProcessor本身就是使用了本身的注解,所以对源码的学习带来了一定的难点,如下图所示,我的AS版本是2020.3.1。但是有的AS版本并没有该图标(该图标可点击),该图标的展示与否也和学习当前Dagger框架有很大干系,切记选对版本。
该源码是我在一次次反复阅读情况下,文章反复蹂躏下得出的结论,所以让我理解到一些重要结论:
-
任何东西的学习都不是一蹴而就的,需要反复的、贯彻的、持之以恒的学习;
-
每一次的学习都会对知识点加深理解;
-
局部的学习只是理解大框架的冰山一角,必须不断深入,最好的方式是贯通一条线,以点带线,以线带面。
- 以点带线,以线带面:点表示切入点;线表示其中一个贯通的功能模块;面表示全方位理解该框架。
可能个人水平的限制并没有能更好的理解Dagger,但是我很庆幸自己能够有机会细品Dagger,感谢自己!!!
DI的理解
该篇文章讲解的是Dagger,最麻烦的是它本身就使用Dagger,还特么给了我一个错误的jar引用,这个糟老头子坏得很!!!
- 有那份闲心可以自行去试下。
Dagger注解的作用何在?就是对一个类的变量在外面(容器)实例化并且赋值给当前类。
Dagger就是为了字段实例化??? 答:然也!!!
Dagger有必要学习吗?
因人而议,因事而议。起码Dagger要会用,一次性的项目感觉也没那个必要,因为Dagger理解起来确实比较费劲,Dagger核心思想DI,dependency injection依赖注入。在外面实例化,把当前类需要变量也在外面赋值,如下:
在ComponentProcessor类中定义的如下InjectBindingRegistry变量,啥都不做,也就这么个玩意,懒得一逼,想天上掉下个馅饼,我呸...
@Inject
InjectBindingRegistry injectBindingRegistry;
还真他么给他等到了,一系列骚操作在DaggerComponentProcessor_ProcessorComponent类中的initialize方法中对该变量进行了实例化injectBindingRegistryImplProvider
,并且在DaggerComponentProcessor_ProcessorComponent类中injectComponentProcessor方法中赋值给了ComponentProcessor类
@CanIgnoreReturnValue
private ComponentProcessor injectComponentProcessor(ComponentProcessor instance) {
ComponentProcessor_MembersInjector.injectInjectBindingRegistry(instance, (InjectBindingRegistry) injectBindingRegistryImplProvider.get());
...
}
ComponentProcessor类依赖注入
可以通过小技巧先看看依赖关系,点击下面的小图标即可知道当前ComponentProcessor变量的实例化的依赖:
他们的依赖的关联关系在ProcessorComponent接口上体现:
如何完成ComponentProcessor类依赖注入
-
在ProcessorComponent接口中定义一个inject方法,表示ComponentProcessor需要注入实例:
void inject(ComponentProcessor processor);
-
ComponentProcessor需要注入哪些实例呢?被Inject修饰的变量:
@Inject InjectBindingRegistry injectBindingRegistry; @Inject SourceFileGenerator<ProvisionBinding> factoryGenerator; @Inject SourceFileGenerator<MembersInjectionBinding> membersInjectorGenerator; @Inject ImmutableList<XProcessingStep> processingSteps; @Inject ValidationBindingGraphPlugins validationBindingGraphPlugins; @Inject ExternalBindingGraphPlugins externalBindingGraphPlugins; @Inject Set<ClearableCache> clearableCaches;
-
这些变量类型,有的存在于ProcessorComponent接口的注解@Component(modules = {})中,有的变量可以在Inject修饰的构造函数中找到,如下选择性罗列,我们表示变量的依赖:
-
injectBindingRegistry类型匹配到InjectBindingRegistryModule的injectBindingRegistry方法的返回类型;
-
validationBindingGraphPlugins匹配到ValidationBindingGraphPlugins使用Inject修饰的构造函数;
-
clearableCaches匹配上ProcessingEnvironmentModule的daggerElementAsClearableCache方法返回类型;
- 以上变量的依赖并不是到此为止,仅仅是一个开始,如下:
-
InjectBindingRegistryModule的injectBindingRegistry方法的参数依赖于InjectBindingRegistryImpl使用Inject修饰的构造函数;
-
InjectBindingRegistryImpl使用Inject修饰的构造函数的参数又会依赖于其他,其他有依赖其他...
所以这里明白了糟老头子为什么把Dagger作为一个注解demo解析,它自身就是一个Dagger demo,而且是深层次的demo,更加方便我们理解。
总结
前言不需要那么多废话,到此为止,下面继续Dagger解析。