0.Dagger2.38.1源码解析指南

本文档提供了一份关于Dagger2.38.1版本的源码解析指南,重点介绍了AndroidProcessor和ComponentProcessor的处理流程。AndroidProcessor涉及Android特定注解的校验和生成,ComponentProcessor则处理Dagger核心注解。文章详细拆解了各个处理步骤,包括MapKey、Inject、AssistedInject等,旨在为开发者提供学习源码的参考框架。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

Dagger2.38.1源码解析指南,相当于一个整体框架的梳理,这样可以避免浪费时间去摸索它的功能板块,给后来者或者再来者提供一个学习参考。当然了,如果对源码一点不了解的情况下,不一定能达到我所说的效果,但是按照我说这个大纲去对照源码解析我感觉也是非常有帮助的。

理想是丰满的,现实是骨感的!!!对我来了一句你写的什么玩意儿肯定也大有人在!!!

当前是基于Dagger2.38.1源码解析得出来的结论,相对来说感觉更加精准,存在不足欢迎讨论。

还有其他代码,这里主要针对核心的AndroidProcessor和ComponentProcessor描述。

Dagger2.38.1版本源码非常有意思的一点是自己使用了自身的注解,所以它本身也是也给Dagger demo样本,为什么这么做的原因个人理解是:开发人员编写代码过程中是否容易出现理解偏差,反正我看代码的时候经常要问问自己我是谁,我到底在干啥!!!

我现在就像问我是谁,我到底在干啥???

想了一会,好吧!我继续,你随意!!!

整体架构

处理的是AndroidProcessor和ComponentProcessor。AndroidProcessor处理android特定注解,ComponentProcessor处理当前Dagger核心注解;

AndroidProcessor

两个板块,一个用于校验MapKey注解修饰的注解;一个用于处理ContributesAndroidInjector注解:先校验+节点生成对象,校验通过后对节点生成代码。

AndroidMapKeyValidator

对AndroidInjectionKey和ClassKey修饰的方法校验。

ContributesAndroidInjectorGenerator

  1. 使用ContributesAndroidInjector修饰的注解的方法节点,先通过AndroidInjectorDescriptor.createIfValid方法生成AndroidInjectorDescriptor对象,生成过程中校验;

  2. 生成实现代码。

这里也并没有完,AndridProcessor中处理的注解还会按照ComponentProcesso的注解规则处理。

ComponentProcessor

这里涉及到自身的注解,我们不做讲解,后面会有专门针对注解进行全面讲解,讲解基于当前2.38.1版本源码,我们仅仅给一个学习源码大纲,可以基于当前大纲指南去一步步学习。

处理注解的核心是ProcessingStepsModule接口的processingSteps方法,当前方法中的Step参数表示针对不同类型注解的处理。

这里有一个思想:横向-各个不同Step类处理不同类型的注解,纵向-每个Setp又按照(1:节点生成对象;2.对象校验;3.component特殊处理成对象;4.对象生成实现代码)步骤处理。

MapKeyProcessingStep

AndroidProcessor处理的AndroidInjectionKey和ClassKey如果被项目使用了,那么在当前step下也会进行二次操作。

处理MapKey修饰的注解:

  1. MapKeyValidator完成校验工作;

  2. 校验通过后,如果①mapKey#unwrapValue = false 或者 ② mapKey#unwrapValue = true && MapKey注解修饰的注解里面唯一的方法返回类型还是一个注解,需要生成相关代码;

InjectProcessingStep 和 InjectBindingRegistry

InjectProcessingStep类

处理Inject修饰的普通方法、变量以及Inject或AssistedInject注解修饰的构造函数,正在的处理放在InjectBindingRegistryImpl类中。

该类主要通过调用InjectBindingRegistryImpl类的tryRegisterConstructor和tryRegisterMembersInjectedType方法;

  1. tryRegisterConstructor方法收集使用Inject或AssistedInject修饰的构造函数生成ProvisionBinding绑定对象;
  • 仅此而已吗???no!!!如果存在Inject修饰的普通方法或变量还会调用tryRegisterMembersInjectedType方法收集;
  1. tryRegisterMembersInjectedType方法收集使用Inject修饰的普通方法或变量所在的父类生成的MembersInjectionBinding绑定对象;
  • 当然也非仅此而已,深入遍历使用Inject修饰的变量(或普通方法)父类直到非Object,将其榨干 - 存在Inject修饰的变量(或普通方法)的父级类都生成MembersInjectionBinding绑定对象并收集。

这里就具体Dagger源码的魅力 - 细致,考虑全面。

InjectBindingRegistry类

这个接口的实现是InjectBindingRegistryImpl类,核心是其内部类BindingsCollection,主要通过该类收集ProvisionBinding绑定对象和MembersInjectionBinding绑定对象,并且在必要的时候对这些绑定对象生成对应的类(在ComponentProcessor调用injectBindingRegistry.generateSourcesForRequiredBindings方法)

  1. 收集ProvisionBinding来源:Inject或AssistedInject修饰的构造函数;

  2. 收集MembersInjectionBinding绑定对象来源:

  • (1)Inject修饰的变量(或普通方法)所在父类(深入遍历其非Object对象,存在Inject修饰的变量或普通方法所在的父级类)生成MembersInjectionBinding绑定对象;

  • (2)对MembersInjector类型的type,在被匹配的情况下(匹配的意思就是相当于方法参数对应到参数类型),会生成MembersInjectionBinding绑定对象;

AssistedInjectProcessingStep

对AssistedInject修饰的构造函数以及该构造函数中的@Assited修饰的参数校验。内容简单。

AssistedFactoryProcessingStep

校验AssistedFactory修饰的类或接口。内容简单。

AssistedProcessingStep

校验Assisted修饰的参数。内容简单。

MonitoringModuleProcessingStep

ProductionComponent或ProductionSubcomponent修饰的类额外生成Module注解修饰的类,按照字面意思理解该生成类起到监控的作用。内容也不难。

MultibindingAnnotationsProcessingStep

校验IntoSet、IntoMap和ElementIntoSet三个注解。内容简单。

BindsInstanceProcessingStep

校验BindsInstance修饰的方法或参数,内容简单。

ModuleProcessingStep

处理Module和ProducerModule注解:

  1. 校验使用该注解的module节点;

  2. 校验通过后对module节点中的bindingMethod绑定方法生成代码:

  • (1)Provides修饰的bindingMethod方法使用FactoryGenerator和InaccessibleMapKeyProxyGnerator类生成;

  • (2)Procues修饰的bindingMethod方法使用ProducerFactoryGenerator和InaccessibleMapKeyProxyGnerator类生成;

  • (3)Binds修饰的BindingMethod使用InaccessibleMapKeyProxyGnerator类生成。

  • (4)以上三个最终都需要调用ModuleConstructorProxyGenerator类的generate方法;

也不是很难。

BindingMethodProcessingStep

收集Mdoule或ProducerModule修饰的module节点中的bindingMethod绑定方法:总共有5个,Providers、Produces、Binds、Multibinds和BindsOptionalOf修饰。

收集到的bindingMethod方法校验。

AnyBindingMethodValidator完成所有bindingMethod校验工作,在BindingMethodValidatorsModule接口的indexValidators方法用于收集并且归类这些bindingMethod方法:

  1. ProvidesMethodValidator收集并校验Provides注解;

  2. ProducesMethodValidator收集并校验Produces注解;

  3. BindsMethodValidator收集并校验Binds注解;

  4. MultibindsMethodValidator收集并校验Multibinds注解;

  5. BindsOptionalOfMethodValidator收集并校验BindsOptionalOf注解;

如果刚开始看这个代码有点懵逼,如果看了我给的这个指南!!!嘿嘿嘿,保证让你精神饱满,充满活力,无任何副作用…咳咳咳,言归正传,继续!!!

ComponentProcessingStep

最难的理解的放在下面压轴讲解。

这块代码处理的是Component、ProductionComponent、Subcomponent、SubProductioncomponent注解,但是使用该注解的component节点还有一系列关联,我们以Component注解为例:

  1. modules和dependencies分别关联module节点和dependency节点;

  2. 步骤1中的modules收集到的是使用Module和ProducerModule注解的module节点,module节点的主街上又关联includes(还是modle节点)和subcomponents(是subcomponent节点);

  3. component节点中还有使用Component.Factory注解的creator节点;

  4. module节点中还有使用Providers、Produces、Binds、Multibinds和BindsOptionalOf修饰的bindingMethod绑定方法;

  5. creator节点中还有使用BindsInstance修饰的方法或方法参数;

除了关联,这里的纵向也是最深:

  1. 针对component节点及其关联生成ComponentDescriptor对象;

  2. 校验该对象;

  3. 全面校验生成的bindingGraph绑定图:

  • (1)Resolved解析绑定关系-核心中的核心;

  • (2)生成bindingGraph对象;

  1. 生成bindingGraph绑定图,并且对bindingGraph校验
  • 3和4我们姑且理解为一个意思,详细看代码会发现略有不同;
  1. 对bindingGraph生成最终component代码,ComponentGenerator类实现,具体的实现放在componentImplementation类,执行generate方法,这里有一个核心,component的入口方法匹配:

-(1) component入口方法是什么?component节点中返回类型非subcomponent节点的方法。

-(2)通过ComponentRequestRepresentations类的getComponentMethod方法完成一系列匹配和代码生成工作,这里主要查看componentImplementation关系图;

  • (3)多提几句,①如果看到源码再去理解,这里就当是故事看,别太较真;②入口方法匹配并且实现代码去看ComponentImplementation的addInterfaceMethods方法;

总结

可在QQ群:575306647 讨论

源码解析github地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值