Dagger2源码分析(上)

Dagger2工作流程分析中,我们认识了@Module, @Component, @Provides, @Inject, @Named等注解。现在我们一起深入下Dagger2是如何生成一系列代码。

准备

推荐文章。

在Java领域内,很多前辈很早已经在做依赖注入的研究与实现,在前辈探索过总结出一些标准,Dagger2作为后来者,必定会跟随前辈的步伐。JSR-330是前辈们总结面向依赖注入使用者的规范,大家需要去了解下。

源码

google在实现Dagger2时,依赖了部分已经比较稳定和完善google的开源库。所以我们需要准备一下源码。

Dagger2依赖auto库中的common,auto-valueauto-service
javapoet是square团队的杰作,使用javapoet可以方便的通过注解生成java源码;

初步看看

clone Dagger2的源码后,我们会看到以下目录结构:
Dagger2的目录结构

目前我们只需要关注corecompiler中的主要代码。

core中定义了支持的自定义注解如下图(除去MembersInjector.java,package-info.java)。
Dagger2的目录结构

以上这些注解的作用以及使用方法在文档中都有,在这里不赘述。

compiler是本次分析的重点,这里完成注解的具体处理策略。

核心源码分析

大家知道Dagger2时在编译时通过分析注解完成依赖注入工作,首先我们来定位下处理注解入口。
我们可以从Dagger2使用google自家的auto-common,auto-serviceauto-value下手。
打开auto源码去看看。
auto开源项目
我们把焦点放在common中的BasicAnnotationProcessor.java和service中的AutoService.java上。

BasicAnnotationProcessor的核心代码分析:

BasicAnnotationProcessor的源码地址

  • 内部接口ProcessingStep,其中annotations方法用于指定ProcessingStep支持处理的注解,process方法用于确定每个注解的处理方式;
  • BasicAnnotationProcessor.java是一个抽象类,抽象方法initSteps,用于指定具体的注解处理步骤;
  • BasicAnnotationProcessor继承自AbstractProcessor,实现public final ImmutableSet<String> getSupportedAnnotationTypes()public final boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv)方法,确定BasicAnnotationProcessor是对注解处理的具体实现的父类;
  • private void process(ImmutableSetMultimap<Class<? extends Annotation>, Element> validElements)是最核心的方法,其中循环ProcessingSteps,依次处理每个step的annotations和process,详细见源码

ComponentProcessor的核心代码分析:

ComponentProcessor的源码地址

ComponentProcessor代码
ComponentProcessor继承自BasicAnnotationProcessor,实现initSteps和postProcess方法。除此之外,还使用AutoService注解修饰。
其中initSteps中返回内容如下:
ComponentProcessor代码
初步结论:
Dagger2把所有注解的处理拆分成上图这些步骤,按照步骤依次执行,生成相关的java代码。其中每个ProcessingStep的任务相关独立。