Arouter之注解处理器

什么是Arouter

Arouter是阿里开源的一款Android组件化的路由框架。它可以实现一个项目中模块间解耦,实现模块在不依赖其他模块的情况下也可以与其他模块进行通信。
Arouter的使用不在此文章做接收,有兴趣到Arouter的github上查看其使用。
Arouter既然是路由框架,那么就少不了路由表,导航、服务等都依赖路由表,而路由表的生成是依赖注解及编译时注解处理器,在编译期间,路由注解器会解析路由注解信息,并按照规则、模板自动生成路由、路由表等java文件。

Android 源码编译流程

注解处理器是在编译期解析源码中的注解信息,在根据规则、模板自动生成相应的java文件,那么注解处理器是在编译期的哪个阶段执行呢?
下图是Android Gradle源码编译的大概流程:

Gradle源码编译是会调用javac的编译程序,接着调用程序中的注解器执行,执行注解器任务发生在源码真正编译之前。

Arouter注解

Arouter目前提供的注解有以下三种:(其中Param被抛弃,推荐使用Autowried替换)

@Route
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface Route {

    /**
     * Path of route
     */
    String path();

    /**
     * Used to merger routes, the group name MUST BE USE THE COMMON WORDS !!!
     */
    String group() default "";

    /**
     * Name of route, used to generate javadoc.
     */
    String name() default "";

    /**
     * Extra data, can be set by user.
     * Ps. U should use the integer num sign the switch, by bits. 10001010101010
     */
    int extras() default Integer.MIN_VALUE;

    /**
     * The priority of route.
     */
    int priority() default -1;
}

@Route的作用范围限定在类、接口、枚举及注解,生命周期为CLASS(只保留到编译器class文件中,jvm运行时被丢弃),参数有:

  • group 路由所属的组别名称,如果不设置,那么会使用path中第一段//之间的字符串作为组别名称
  • path 路由路径,必须以/开头
  • name 路由名称,用于生成javadoc文档
  • extras 路由父级信息,int类型,用途是int由32位组成,每一位代表一种状态,可以使用这个特性给予路由一些特殊的标志,如是否需要登录、安全校验等。
  • priority 路由优先级
@Autowired
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.CLASS)
public @interface Autowired {

    // Mark param's name or service name.
    String name() default "";

    // If required, app will be crash when value is null.
    // Primitive type wont be check!
    boolean required() default false;

    // Description of the field
    String desc() default "";
}

@Autowrited的作用范围是字段,生命周期为CLASS(只保留到编译器class文件中,jvm运行时被丢弃),参数有:

  • name 标记属性的名称或者服务名称
  • required 表示属性是否不能为空,默认为false
  • desc 属性的描述信息
@Interceptor
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.CLASS)
public @interface Interceptor {
    /**
     * The priority of interceptor, ARouter will be excute them follow the priority.
     */
    int priority();

    /**
     * The name of interceptor, may be used to generate javadoc.
     */
    String name() default "Default";
}

@Interceptor 的作用范围是类、接口、枚举及注解,生命周期为CLASS(只保留到编译器class文件中,jvm运行时被丢弃),参数有:

  • priority 拦截器的优先级
  • name 拦截器的名称

抽象注解处理器AbstractProcessor

注解器抽象类是AbstractProcessor,一般自定义注解器都需要继承并实现其抽象方法,主要方法有:

  • getSupportedOptions:返回gradle 配置信息options中支持的key,比如Arouter模块gradle的option定义的模块名称:
android {
    defaultConfig {
        ...
        javaCompileOptions {
            annotationProcessorOptions {
                arguments = [AROUTER_MODULE_NAME: project.getName()]
            }
        }
    }
}
  • getSupportedSourceVersion: 返回配置的源码版本,即JDK的版本
  • init:注解处理器初始化函数
  • process:注解处理器执行主体

注解器函数执行的流程是:构造方法——》init方法——》process方法

注解处理器中一些主要的类:

Element

Element是一个接口,它只在编译期存在和Type是有区别的,Element表示程序的一个元素,如:package、class、interface、method、成员变量、函数参数、泛型类型等。它可以提供当前元素的类型信息,如:类型名称、字段名称、包等。
Element常见的子类有:

  • ExecutableElement:表示类或接口中的方法、构造函数construt、实例初始化函数init、类初始化函数cinit.
  • PackageElement :表示包程序元素,它提供对包及其成员的访问。
  • TypeElement:表示类、接口元素,它提供对类/接口的类型和方法信息的访问。注意枚举属于类类型,而注解属于接口类型。
  • TypeParameterElement:表示类、接口、方法、构造函数的泛型类型,如泛型类型T
  • VariableElement:表示字段、枚举常量、方法/构造函数的参数、本地变量、资源变量、异常参数

Element常见的函数有:

ProcessingEnvironment

注解器处理器中编译器环境信息,可以提供文件生成器、类型处理工具类、元素处理工具类、日志打印等

Filer

注解处理器文件生成器,Arouter使用文件生成器配合使用squareup的javapoet库生成java源码文件

Types

类型处理工具类

Elements

元素处理工具类

Messager

日志工具类

Arouter注解处理器

Arouter注解处理器有:RouteProcessor、AutowiredProcessor、InterceptorProcessor,它们都继承与BaseProcessor,而BaseProcessor继承于AbstractProcessor。

BaseProcessor
public abstract class BaseProcessor extends AbstractProcessor {
    Filer mFiler;
    Logger logger;
    Types types;
    Elements elementUtils;
    TypeUtils typeUtils;
    // Module name, maybe its 'app' or others
    String moduleName = null;
    // If need generate router doc
    boolean generateDoc;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        //从编译环境中获取文件生成器
        mFiler = processingEnv.getFiler();
        //从编译环境中获取类型处理工具类,主要是的对TypeMirror的操作
        types = processingEnv.getTypeUtils();
        //从编译环境中获取元素处理工具类
        elementUtils = processingEnv.getElementUtils();
        //将类型处理工具类与元素处理工具类进行包装,作为arouter注解器的类型处理工具类
        typeUtils = new TypeUtils(types, elementUtils);
        //将编译环境中获取的日志工具类包装为arouter注解器的日志工具类
        logger = new Logger(processingEnv.getMessager());

        // Attempt to get user configuration [moduleName]
        /**
        * 这里就是从每个模块的build.gradle的annotationProcessorOptions配置中取值模块名称
        * 需要使用组件化的都需要配置改options,key对应的值就是模块名称
        * 模块名称作为路由rootMap中的key,每个模块都对应生成一个root
        */
        Map options = processingEnv.getOptions();
        if (MapUtils.isNotEmpty(options)) {
            moduleName = options.get(KEY_MODULE_NAME);
            generateDoc = VALUE_ENABLE.equals(options.get(KEY_GENERATE_DOC_NAME));
        }

        if (StringUtils.isNotEmpty(moduleName)) {
            //如果模块名称不为空,则将非数字、字母、下划线的都转为空字符串
            moduleName = moduleName.replaceAll("[^0-9a-zA-Z_]+", "");

            logger.info("The user has configuration the module name, it was [" + moduleName + "]");
        } else {
            //如果模块名称为空,则抛出异常
            logger.error(NO_MODULE_NAME_TIPS);
            throw new RuntimeException("ARouter::Compiler >>> No module name, for more information, look at gradle log.");
        }
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        //配置源码版本,即JDK的版本
        return SourceVersion.latestSupported();
    }

    @Override
    public Set getSupportedOptions() {
        //配置build.gradle中annotationProcessorOptions中optios的可以
       //KEY_MODULE_NAME是一个字符串"AROUTER_MODULE_NAME"
        return new HashSet() {{
            this.add(KEY_MODULE_NAME);
            this.add(KEY_GENERATE_DOC_NAME);
        }};
    }
}
RouteProcessor

RouteProcessor是生成一个模块的路由表的注解处理器,模块的路由表包括:路由组表、每个路由组组内路由表。

@AutoService(Processor.class)
@SupportedAnnotationTypes({ANNOTATION_TYPE_ROUTE, ANNOTATION_TYPE_AUTOWIRED})
public class RouteProcessor extends BaseProcessor {
    //组内路由组表,key是组名称,value是路由组内的路由RouteMeta集合
    private Map> groupMap = new HashMap<>(); // ModuleName and routeMeta.
    //路由组表,key是组名称,value是路由组类RouteGroup类名
    private Map rootMap = new TreeMap<>();  // Map of root metas, used for generate class file in order.
    //Provider的类型信息
    private TypeMirror iProvider = null;
    //文档写工具类
    private Writer docWriter;       // Writer used for write doc

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        //初始化注解处理器
        if (generateDoc) {
            //如果要生成文档
            try {
                //使用文件生成器创建文档,打开文档并获取读写器
                docWriter = mFiler.createResource(
                        StandardLocation.SOURCE_OUTPUT,
                        PACKAGE_OF_GENERATE_DOCS,
                        "arouter-map-of-" + moduleName + ".json"
                ).openWriter();
            } catch (IOException e) {
                logger.error("Create doc writer failed, because " + e.getMessage());
            }
        }
        //获取模板中IProvider的类型信息对象
        iProvider = elementUtils.getTypeElement(Consts.IPROVIDER).asType();

        logger.info(">>> RouteProcessor init. <<<");
    }

    /**
     * {@inheritDoc}
     *
     * @param annotations
     * @param roundEnv
     */
    @Override
    public boolean process(Set annotations, RoundEnvironment roundEnv) {
        //执行注解器处理程序
        if (CollectionUtils.isNotEmpty(annotations)) {
            //如果存在注解信息
            //从编译环境对象中获取所有被@Route注解修饰的元素
            Set routeElements = roundEnv.getElementsAnnotatedWith(Route.class);
            try {
                logger.info(">>> Found routes, start... <<<");
                //调用parseRoutes方法对路由元素进行解析
                this.parseRoutes(routeElements);

            } catch (Exception e) {
                logger.error(e);
            }
            return true;
        }

        return false;
    }

    private void parseRoutes(Set routeElements) throws IOException {
       //解析路由信息 
       if (CollectionUtils.isNotEmpty(routeElements)) {
            // prepare the type an so on.
            
            logger.info(">>> Found routes, size is " + routeElements.size() + " <<<");
            //清空路由组表
            rootMap.clear();
            //获取android.app.Activity的类型信息对象
            TypeMirror type_Activity = elementUtils.getTypeElement(ACTIVITY).asType();
            //获取android.app.Service的类型信息对象
            TypeMirror type_Service = elementUtils.getTypeElement(SERVICE).asType();
            //获取android.app.Fragment的类型信息对象
            TypeMirror fragmentTm = elementUtils.getTypeElement(FRAGMENT).asType();
            //获取android.support.v4.app.Fragment的类型信息对象
            TypeMirror fragmentTmV4 = elementUtils.getTypeElement(Consts.FRAGMENT_V4).asType();

            // Interface of ARouter
            //获取IRouteGroup的类型元素对象
            TypeElement type_IRouteGroup = elementUtils.getTypeElement(IROUTE_GROUP);
            //获取IProviderGroup的类型元素对象
            TypeElement type_IProviderGroup = elementUtils.getTypeElement(IPROVIDER_GROUP);
            //获取RouteMeta的类名对象,用于替换$T.build:javapoet生成java文件的组成部分
            ClassName routeMetaCn = ClassName.get(RouteMeta.class);
            //获取RouteType的类名对象,用于替换RouteMeta.build($T.ACTIVITY):javapoet生成java文件的组成部分
            ClassName routeTypeCn = ClassName.get(RouteType.class);

            /*
              1、创建生成RouteRoot、RouteGroup类中loadInto方法的参数类型
               Build input type, format as :

               ```Map>```
             */
            //javapoet生成java文件的组成部分
            //生成RouteRoot文件的loadInto方法的参数类型对象,类型为Map>
            ParameterizedTypeName inputMapTypeOfRoot = ParameterizedTypeName.get(
                    ClassName.get(Map.class), //参数类型
                    ClassName.get(String.class), //Map的key
                    ParameterizedTypeName.get(  //Map的value,它是泛型又是参数类型对象
                            ClassName.get(Class.class),
                            WildcardTypeName.subtypeOf(ClassName.get(type_IRouteGroup))
                    )
            );

            /*

              ```Map```
             */
            //javapoet生成java文件的组成部分
            //生成RouteGroup类文件的loadInto方法的参数类型对象,类型为Map
            ParameterizedTypeName inputMapTypeOfGroup = ParameterizedTypeName.get(
                    ClassName.get(Map.class),
                    ClassName.get(String.class),
                    ClassName.get(RouteMeta.class)
            );

            /*
             2、定义RouteRoot、RouteGroup、Provider等类的loadInto方法的参数对象
              Build input param name.
             */
            //javapoet生成java文件的组成部分
            //生成root文件中loadInto方法的参数:类型为Map>,参数名称为routes
            ParameterSpec rootParamSpec = ParameterSpec.builder(inputMapTypeOfRoot, "routes").build();
            //生成group文件中loadInto方法的参数:类型为Map,参数名称为atlas
            ParameterSpec groupParamSpec = ParameterSpec.builder(inputMapTypeOfGroup, "atlas").build();
            //生成provider文件中loadInto方法的参数:类型为Map,参数名称为providers
            ParameterSpec providerParamSpec = ParameterSpec.builder(inputMapTypeOfGroup, "providers").build();  // Ps. its param type same as groupParamSpec!

            /*
              3、生成对应的RouteRoot类方法loadInto的Builder,在后面会使用到
              Build method : 'loadInto'
             */
            //生成对应的Root文件中的loadInto方法Builder对象
            MethodSpec.Builder loadIntoMethodOfRootBuilder = MethodSpec.methodBuilder(METHOD_LOAD_INTO) //方法名为:loadInto
                    .addAnnotation(Override.class) //重新
                    .addModifiers(PUBLIC) //方法为public
                    .addParameter(rootParamSpec); //方法参数Map> routes

            //  Follow a sequence, find out metas of group first, generate java file, then statistics them as root.
            //4、遍历所有路由元素
            //将路由元素进行分组,每个group有多个路由,组成一个路由分组表groupMap,key是分组名,value是Set集合的组内的路由列表
            //先根据路由元素中的信息构建为一个RouteMeta(路由元信息),对其分组,再将组统计为root
            for (Element element : routeElements) {
                //获取路由元素的类型信息
                TypeMirror tm = element.asType();
                //获取路由元素中的@Route注解信息
                Route route = element.getAnnotation(Route.class);
                //声明路由元信息
                RouteMeta routeMeta;

                // Activity or Fragment
                if (types.isSubtype(tm, type_Activity) || types.isSubtype(tm, fragmentTm) || types.isSubtype(tm, fragmentTmV4)) {
                    //如果路由元素是Activity或者fragment或者support v4的fragment的子类
                    // Get all fields annotation by @Autowired
                    //获取该元素中所有被@Autowrited注解的字段
                    //被@Autowrited注解的字段的类型
                    Map paramsType = new HashMap<>();
                    //被@Autowrited注解的字段的注入配置
                    Map injectConfig = new HashMap<>();
                    //收集@Autowrited注解并生成注入配置信息
                    injectParamCollector(element, paramsType, injectConfig);

                    if (types.isSubtype(tm, type_Activity)) {
                        // Activity
                        //如果路由元素是Activity
                        logger.info(">>> Found activity route: " + tm.toString() + " <<<");
                        /**
                        * 构建Activity类型的路由元信息
                        * route: 路由注解信息,通过它可以得到路由group、path、name等信息
                        * element:路由注解所修饰的元素,这里是Activity的子类
                        * RouteType:枚举类型,表示当前路由为Activity类型
                        * paramsType:Activity中@Autowrited修饰的元素的类型列表
                        */
                        routeMeta = new RouteMeta(route, element, RouteType.ACTIVITY, paramsType);
                    } else {
                        //如果路由元素是 Fragment
                         /**
                        * 构建Fragment类型的路由元信息
                        * route: 路由注解信息,通过它可以得到路由group、path、name等信息
                        * element:路由注解所修饰的元素,这里是Fragment的子类
                        * RouteType:枚举类型,表示当前路由为Fragment类型
                        * paramsType:Fragment中@Autowrited修饰的元素的类型列表
                        */
                        logger.info(">>> Found fragment route: " + tm.toString() + " <<<");
                        routeMeta = new RouteMeta(route, element, RouteType.parse(FRAGMENT), paramsType);
                    }
                    //设置路由元需要注入的配置信息,及@Autowrited的配置信息
                    routeMeta.setInjectConfig(injectConfig);
                } else if (types.isSubtype(tm, iProvider)) {         // IProvider
                    //如果路由元素是Arouter的IProvider的子类
                    logger.info(">>> Found provider route: " + tm.toString() + " <<<");
                    /**
                        * 构建Provider类型的路由元信息
                        * route: 路由注解信息,通过它可以得到路由group、path、name等信息
                        * element:路由注解所修饰的元素,这里是IProvider的子类
                        * RouteType:枚举类型,表示当前路由为Provider类型
                        * paramsType:空,即不支持@Autowrited依赖注入
                        */
                    routeMeta = new RouteMeta(route, element, RouteType.PROVIDER, null);
                } else if (types.isSubtype(tm, type_Service)) {           // Service
                   //如果路由元素是Service
                    logger.info(">>> Found service route: " + tm.toString() + " <<<");
                    /**
                        * 构建Service类型的路由元信息
                        * route: 路由注解信息,通过它可以得到路由group、path、name等信息
                        * element:路由注解所修饰的元素,这里是Service的子类
                        * RouteType:枚举类型,表示当前路由为Service类型
                        * paramsType:空,即不支持@Autowrited依赖注入
                        */
                    routeMeta = new RouteMeta(route, element, RouteType.parse(SERVICE), null);
                } else {
                    //如果路由元素不是上述类型,那么抛出异常,即路由元素仅支持Activity、Fragment、Service、Arouter的Provider
                    throw new RuntimeException("The @Route is marked on unsupported class, look at [" + tm.toString() + "].");
                }
                //对路由进行分组并进行组内排序
                //将同组的路由保存在一个Set集合中,并且使用Group名作为key保存到groupMap中
                categories(routeMeta);
            }
            //构建Provider的loadInto方法Builder对象
            MethodSpec.Builder loadIntoMethodOfProviderBuilder = MethodSpec.methodBuilder(METHOD_LOAD_INTO) //方法名为loadInto
                    .addAnnotation(Override.class)//重写
                    .addModifiers(PUBLIC) //public
                    .addParameter(providerParamSpec); //provider的loadInto方法的参数是:Map providers
            
            //路由文档Map
            Map> docSource = new HashMap<>();

            // Start generate java source, structure is divided into upper and lower levels, used for demand initialization.
            for (Map.Entry> entry : groupMap.entrySet()) {
                //遍历路由组
                //获取路由组名称
                String groupName = entry.getKey();
               //构建路由组RouteGroup的loadInto方法的Builder
                MethodSpec.Builder loadIntoMethodOfGroupBuilder = MethodSpec.methodBuilder(METHOD_LOAD_INTO)
                        .addAnnotation(Override.class)
                        .addModifiers(PUBLIC)
                        .addParameter(groupParamSpec);
               //路由文档列表
                List routeDocList = new ArrayList<>();

                // Build group method body
                Set groupData = entry.getValue();
                for (RouteMeta routeMeta : groupData) {
                   //遍历组内路由列表
                   //将路由元信息转为路由文档信息
                    RouteDoc routeDoc = extractDocInfo(routeMeta);
                    //获取路由真实类名对象
                    ClassName className = ClassName.get((TypeElement) routeMeta.getRawType());

                    switch (routeMeta.getType()) {
                        case PROVIDER:  // Need cache provider's super class
                            //如果路由类型是Provider
                           //获取Provider实现的接口类型列表包括其父类的
                            List interfaces = ((TypeElement) routeMeta.getRawType()).getInterfaces();
                            for (TypeMirror tm : interfaces) {
                                //遍历接口列表
                                
                                routeDoc.addPrototype(tm.toString());
                                /**
                                * 构建Provider类文件中方法loadInto的内容
                                * Provider文件其实类似Group文件,只不过provider中Map的key不是path而是实现了IProvider接口的类的全限定名
                                */
                                if (types.isSameType(tm, iProvider)) {   // Its implements iProvider interface himself.
                                    // This interface extend the IProvider, so it can be used for mark provider
                                    //如果接口tm就是IProvider
                                   //生成Provider的loadInto方法内容
                                   /**
                                   * 方法内容为:
                                   * providers.put(ProviderImpl.classname, RouteMeta.Build(RouteType.XXX, ProviderImpl.class, routePath, routeGroup, null, routePriority, routeExtra))
                                   * 其中RouteMeta.build调用的是build(RouteType type, Class destination, String path, String group, Map paramsType, int priority, int extra)
                                    * 其实就是构建出Provider的路由元信息,用Provider的类权限定名做为key,Provider的路由元信息做为value,存储在providers的Map中
                                   */
                                    loadIntoMethodOfProviderBuilder.addStatement(
                                            "providers.put($S, $T.build($T." + routeMeta.getType() + ", $T.class, $S, $S, null, " + routeMeta.getPriority() + ", " + routeMeta.getExtra() + "))",
                                            (routeMeta.getRawType()).toString(),
                                            routeMetaCn,
                                            routeTypeCn,
                                            className, //Iprovider的最终实现类
                                            routeMeta.getPath(),
                                            routeMeta.getGroup());
                                } else if (types.isSubtype(tm, iProvider)) {
                                    // This interface extend the IProvider, so it can be used for mark provider
                                    //如果接口是IProvider的子类
                                     //生成Provider的loadInto方法内容
                                   /**
                                   * 方法内容为:
                                   * providers.put(ProviderImpl.classname, RouteMeta.Build(RouteType.XXX, ProviderImpl.class, routePath, routeGroup, null, routePriority, routeExtra))
                                   * 其中RouteMeta.build调用的是build(RouteType type, Class destination, String path, String group, Map paramsType, int priority, int extra)
                                    * 其实就是构建出Provider的路由元信息,用Provider的类权限定名做为key,Provider的路由元信息做为value,存储在providers的Map中
                                   */
                                    loadIntoMethodOfProviderBuilder.addStatement(
                                            "providers.put($S, $T.build($T." + routeMeta.getType() + ", $T.class, $S, $S, null, " + routeMeta.getPriority() + ", " + routeMeta.getExtra() + "))",
                                            tm.toString(),    // So stupid, will duplicate only save class name.
                                            routeMetaCn,
                                            routeTypeCn,
                                            className, //Iprovider的最终实现类
                                            routeMeta.getPath(),
                                            routeMeta.getGroup());
                                }
                            }
                            break;
                        default:
                            break;
                    }

                    // Make map body for paramsType
                    /**
                    * 生成@Autowrited修饰的元素的类型map
                    */
                    StringBuilder mapBodyBuilder = new StringBuilder();
                    //获取@Autowrited修饰的元素的类型map
                    Map paramsType = routeMeta.getParamsType();
                    //获取@Autowrited修饰的元素的注入配置信息
                    Map injectConfigs = routeMeta.getInjectConfig();
                    if (MapUtils.isNotEmpty(paramsType)) {
                        //如果存在@Autowrited修饰的元素
                        
                        List paramList = new ArrayList<>();
                    
                        for (Map.Entry types : paramsType.entrySet()) {
                            //遍历@Autowrited修饰的元素的类型
                            //将@Autowrited修饰的元素的类型转为字符串形式:put("typeKey", typeValue);字符串放入mapBodyBuilder中
                            mapBodyBuilder.append("put(\"").append(types.getKey()).append("\", ").append(types.getValue()).append("); ");
                            
                            //生成路由文档的参数信息
                            RouteDoc.Param param = new RouteDoc.Param();
                            Autowired injectConfig = injectConfigs.get(types.getKey());
                            param.setKey(types.getKey());
                            param.setType(TypeKind.values()[types.getValue()].name().toLowerCase());
                            param.setDescription(injectConfig.desc());
                            param.setRequired(injectConfig.required());

                            paramList.add(param);
                        }

                        routeDoc.setParams(paramList);
                    }
                    //这里是路由中@Autowrited修饰的元素的类型map内容部分
                    String mapBody = mapBodyBuilder.toString();
                    /**
                    * 定义group文件的loadInto方法的内容:
                    * atlas.put(routePath, RouteMeta.build(RouteType.xxx, RouteImpl.class, routePath, routeGroup, autowritedmapBody, routePriority, routeExtra))
                    * 其实就是构建路由元对象RouteMeta,并放入路由组atlas中,atlas是一个Map,
                    * key 是路由路径,value是RouteMeta
                    */
                    loadIntoMethodOfGroupBuilder.addStatement(
                            "atlas.put($S, $T.build($T." + routeMeta.getType() + ", $T.class, $S, $S, " + (StringUtils.isEmpty(mapBody) ? null : ("new java.util.HashMap(){{" + mapBodyBuilder.toString() + "}}")) + ", " + routeMeta.getPriority() + ", " + routeMeta.getExtra() + "))",
                            routeMeta.getPath(),
                            routeMetaCn,
                            routeTypeCn,
                            className,
                            routeMeta.getPath().toLowerCase(),
                            routeMeta.getGroup().toLowerCase());
                
                    routeDoc.setClassName(className.toString());
                    routeDocList.add(routeDoc);
                }

                // Generate groups
                //路由组Group文件名:ARouter$$Group$$groupName
                String groupFileName = NAME_OF_GROUP + groupName;
                //使用javapoet集合文件生成器mFiler生成RouteGroup文件
                JavaFile.builder(PACKAGE_OF_GENERATE_FILE, //包名
                        TypeSpec.classBuilder(groupFileName) //类名
                                .addJavadoc(WARNING_TIPS)
                                .addSuperinterface(ClassName.get(type_IRouteGroup)) //实现IRouteGroup接口
                                .addModifiers(PUBLIC) //public
                                .addMethod(loadIntoMethodOfGroupBuilder.build()) //类的方法loadInto
                                .build()
                ).build().writeTo(mFiler);

                logger.info(">>> Generated group: " + groupName + "<<<");
                //将group放入模块路由组表Map中,key是组名,value是Group的类名字符串
                rootMap.put(groupName, groupFileName);
                docSource.put(groupName, routeDocList);
            }

            if (MapUtils.isNotEmpty(rootMap)) {
                // Generate root meta by group name, it must be generated before root, then I can find out the class of group.
                //如果路由组表不为空
                for (Map.Entry entry : rootMap.entrySet()) {
                    //遍历路由组表
                    //生成模块根路由RouteRoot的loadInto方法的内容:
                    //routes.put(groupName, RouteGroup),routes是loadInto方法的参数Map> routes
                    loadIntoMethodOfRootBuilder.addStatement("routes.put($S, $T.class)", entry.getKey(), ClassName.get(PACKAGE_OF_GENERATE_FILE, entry.getValue()));
                }
            }
            //输出Route文档
            // Output route doc
            if (generateDoc) {
                docWriter.append(JSON.toJSONString(docSource, SerializerFeature.PrettyFormat));
                docWriter.flush();
                docWriter.close();
            }

            // Write provider into disk
            //使用javapoet结合文件生成器mFiler生成Provider文件
            //provider类文件名也是类名:ARouter$$Providers$$moduleName
            String providerMapFileName = NAME_OF_PROVIDER + SEPARATOR + moduleName; //
            JavaFile.builder(PACKAGE_OF_GENERATE_FILE,  //provider包名
                    TypeSpec.classBuilder(providerMapFileName) //provider类名
                            .addJavadoc(WARNING_TIPS)
                            .addSuperinterface(ClassName.get(type_IProviderGroup)) //provider实现的接口IProviderGroup
                            .addModifiers(PUBLIC)
                            .addMethod(loadIntoMethodOfProviderBuilder.build()) 
                            .build()
            ).build().writeTo(mFiler);

            logger.info(">>> Generated provider map, name is " + providerMapFileName + " <<<");

            // Write root meta into disk.
             //使用javapoet结合文件生成器mFiler生成RouteRoot文件
            //模块根路由类文件名也是类名:ARouter$$Root$$moduleName
            String rootFileName = NAME_OF_ROOT + SEPARATOR + moduleName;
            JavaFile.builder(PACKAGE_OF_GENERATE_FILE, //包名
                    TypeSpec.classBuilder(rootFileName) //类名
                            .addJavadoc(WARNING_TIPS)
                            .addSuperinterface(ClassName.get(elementUtils.getTypeElement(ITROUTE_ROOT))) //RouteRoot实现的接口IRouteRoot
                            .addModifiers(PUBLIC)
                            .addMethod(loadIntoMethodOfRootBuilder.build()) //添加RouteRoot的方法loadInto
                            .build()
            ).build().writeTo(mFiler);

            logger.info(">>> Generated root, name is " + rootFileName + " <<<");
        }
    }

    /**
     * Recursive inject config collector.
     *
     * @param element current element.
     */
    private void injectParamCollector(Element element, Map paramsType, Map injectConfig) {
        //收集@Route修饰的元素element下的所有@Autowrited的信息
        for (Element field : element.getEnclosedElements()) {
            //获取@Route修饰的元素element下的所有子元素,包括字段、方法
            if (field.getKind().isField() && field.getAnnotation(Autowired.class) != null && !types.isSubtype(field.asType(), iProvider)) {
                //如果子元素是字段且被@Autorited注解修饰,且字段不是provider子类
                // It must be field, then it has annotation, but it not be provider.
                //获取字段@Autorited注解对象
                Autowired paramConfig = field.getAnnotation(Autowired.class);
                //获取字段名或者别名
                String injectName = StringUtils.isEmpty(paramConfig.name()) ? field.getSimpleName().toString() : paramConfig.name();
                //获取字段类型,并存入类型表中
                paramsType.put(injectName, typeUtils.typeExchange(field));
                //注入名称和@Autorited注解对象放入依赖注入配置表中
                injectConfig.put(injectName, paramConfig);
            }
        }

        // if has parent?
        //@Route修饰的元素element的父类类型信息
        TypeMirror parent = ((TypeElement) element).getSuperclass();
        if (parent instanceof DeclaredType) {
            //父类类型信息是类或接口
            //父类类型信息对象转为程序元素
            Element parentElement = ((DeclaredType) parent).asElement();
            if (parentElement instanceof TypeElement && !((TypeElement) parentElement).getQualifiedName().toString().startsWith("android")) {
                //如果父类元素是类/接口,且父类元素不是android包下的类
                //继续递归调用injectParamCollector收集@Autowrited注解信息
                injectParamCollector(parentElement, paramsType, injectConfig);
            }
        }
    }

    /**
     * Extra doc info from route meta
     *
     * @param routeMeta meta
     * @return doc
     */
    private RouteDoc extractDocInfo(RouteMeta routeMeta) {
        //将路由元信息类RouteMeta转为路由文档类
        RouteDoc routeDoc = new RouteDoc();
        routeDoc.setGroup(routeMeta.getGroup());
        routeDoc.setPath(routeMeta.getPath());
        routeDoc.setDescription(routeMeta.getName());
        routeDoc.setType(routeMeta.getType().name().toLowerCase());
        routeDoc.setMark(routeMeta.getExtra());

        return routeDoc;
    }

    /**
     * Sort metas in group.
     *
     * @param routeMete metas.
     */
    private void categories(RouteMeta routeMete) {
        //对路由进行分组
        if (routeVerify(routeMete)) {
            //校验路由元信息,如果是合法的路由,则:
            logger.info(">>> Start categories, group = " + routeMete.getGroup() + ", path = " + routeMete.getPath() + " <<<");
            //根据路由组名从路由组表groupMap获取组内路由集合
            Set routeMetas = groupMap.get(routeMete.getGroup());
            if (CollectionUtils.isEmpty(routeMetas)) {
                //如果组内路由集合为空
                //新建一个组内路由集合
                Set routeMetaSet = new TreeSet<>(new Comparator() {
                    @Override
                    public int compare(RouteMeta r1, RouteMeta r2) {
                        try {
                            return r1.getPath().compareTo(r2.getPath());
                        } catch (NullPointerException npe) {
                            logger.error(npe.getMessage());
                            return 0;
                        }
                    }
                });
                //将路由加入组内路由集合
                routeMetaSet.add(routeMete);
                //路由组表groupMap加入新的路由组,key是路由组名,value是组内路由集合
                groupMap.put(routeMete.getGroup(), routeMetaSet);
            } else {
                //如果组内路由集合不为空
                //将路由加入组内路由集合
                routeMetas.add(routeMete);
            }
        } else {
            logger.warning(">>> Route meta verify error, group is " + routeMete.getGroup() + " <<<");
        }
    }

    /**
     * Verify the route meta
     *
     * @param meta raw meta
     */
    private boolean routeVerify(RouteMeta meta) {
         //校验路由元信息
        //路由路径
        String path = meta.getPath();

        if (StringUtils.isEmpty(path) || !path.startsWith("/")) {   // The path must be start with '/' and not empty!
            //如果路由路径为空或者不是以/开头,则返回false,表示非法的路由
            return false;
        }

        if (StringUtils.isEmpty(meta.getGroup())) { // Use default group(the first word in path)
            //如果路由没有设置组名
            //则使用路由路径path的第一度//中的内容作为路由组名
            try {
                String defaultGroup = path.substring(1, path.indexOf("/", 1));
                if (StringUtils.isEmpty(defaultGroup)) {
                    return false;
                }

                meta.setGroup(defaultGroup);
                return true;
            } catch (Exception e) {
                logger.error("Failed to extract default group! " + e.getMessage());
                return false;
            }
        }

        return true;
    }
}

根据上述对RouteProcessor源码解析,我们可以得出以下结论:
1、RouteProcessor注解处理器处理的是@Route注解
2、RouteProcessor会生成三类java文件,分别是:RouteRoot文件(每个模块一个,模块根路由表文件)、RouteGroup文件(每个模块存在多个分组,每个组对应一个RouteGroup文件)、Provider文件(每个模块一个,模块提供的服务表文件)

  • RouteRoot: 模块根路由表文件,每个模块只有一个文件,实现IRouteRoot接口,维护模块根路由Map,key是模块名(即路由组名)、value是路由组RouteGroup实现的类
  • RouteGroup:每组路由表文件,每组对应一个路由组文件,实现IRouteGroup接口,维护路由组Map, key是组名,value是有RouteMeta组成的路由Set集合
  • Provider:模块提供的服务表文件,只有一个文件,实现IProvider接口,维护providerMap,key是provider真实实现类全限定名,value是表示provider类型的RouteMeta对象

3、RouteProcessor是围绕@route的注解,解析生成RouteRoot、RouteGroup、Provider这三种文件,其流程:
3.1、从编译环境RoundEnvironment中读取所有被@Route注解修饰的元素列表
3.2、生成路由表文件RouteRoot的方法loadIntod的参数及名称
3.3、生成路由组文件RouteGroup的方法loadInto的参数及名称
3.4、生成路由组文件Provider的方法loadInto的参数及名称
3.5、遍历@Route注解修饰的元素列表
3.5.1、根据注解信息生成路由元信息对象RouteMeta,同时收集activity、fragment中需要依赖注入@Autowrited的参数类型及配置信息
3.5.2、对RouteMeta进行分组,把RouteMeta放入对应的路由组表groupMap中,组名使用注解中的group,如果为空则使用path中第一段//作为组名
3.6、遍历分好组的路由组groupMap
3.6.1、对provider进行过滤,并生成provider文件的方法及方法参数及方法内容;
3.6.2、同时生成每个路由组对应的RouteGroup文件中的方法及参数及方法内容
3.6.3、生成每个路由组对应的RouteGroup文件
3.6.4、将模块中的路由组RouteGroup进行归档到根路由表routeMap中
3.7、遍历根路由表routeMap生成根路由文件的loadInto方法的方法内容
3.8、根据生成provider的loadInto方法、方法参数、参数名称、方法内容生成provider文件
3.9、根据生成根路由的loadInto方法、方法参数、参数名称、方法内容生成根路由文件RouteRoot

AutowiredProcessor

AutowiredProcessor注解处理器是用来生成依赖注入工具类,对被@Autowrited注解修饰的字段进行赋值,我们先分析其源码:

@AutoService(Processor.class)
@SupportedAnnotationTypes({ANNOTATION_TYPE_AUTOWIRED})
public class AutowiredProcessor extends BaseProcessor {
   //autowrited关系表,key是包含@Autowrited的类类型,value是类中此类中被@Autowrited注解的元素列表
    private Map> parentAndChild = new HashMap<>();   // Contain field need autowired and his super class.
    //Arouter类名对象
    private static final ClassName ARouterClass = ClassName.get("com.alibaba.android.arouter.launcher", "ARouter");
    private static final ClassName AndroidLog = ClassName.get("android.util", "Log");

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
         //初始化AutowiredProcessor注解处理器
        logger.info(">>> AutowiredProcessor init. <<<");
    }

    @Override
    public boolean process(Set set, RoundEnvironment roundEnvironment) {
        //执行AutowiredProcessor注解处理器的处理程序
        if (CollectionUtils.isNotEmpty(set)) {
            //如果程序存在类、接口等类类型,则:
            try {
                logger.info(">>> Found autowired field, start... <<<");
                //从编译环境对象中读取所有被@Autowired注解修饰的元素,并进行分类解析
                categories(roundEnvironment.getElementsAnnotatedWith(Autowired.class));
                //生成Autowrited依赖注入工具类
                generateHelper();

            } catch (Exception e) {
                logger.error(e);
            }
            return true;
        }

        return false;
    }

    private void generateHelper() throws IOException, IllegalAccessException {
        //生成依赖注入工具类
        //获取注射器ISyringe的类类型,是生成java类需要实现的接口类型
        TypeElement type_ISyringe = elementUtils.getTypeElement(ISYRINGE);
        //获取序列化服务SerializationService的类类型,它用于解析json字符串,是操作对象、列表、map等数据的处理类
        TypeElement type_JsonService = elementUtils.getTypeElement(JSON_SERVICE);
        //获取IProvider的类型信息对象
        TypeMirror iProvider = elementUtils.getTypeElement(Consts.IPROVIDER).asType();
        //获取android.app.Activity的类型信息对象
        TypeMirror activityTm = elementUtils.getTypeElement(Consts.ACTIVITY).asType();
        //获取android.app.Fragment的类型信息对象
        TypeMirror fragmentTm = elementUtils.getTypeElement(Consts.FRAGMENT).asType();
        //获取android.support.v4.app.Fragment的类型信息对象
        TypeMirror fragmentTmV4 = elementUtils.getTypeElement(Consts.FRAGMENT_V4).asType();

        // Build input param name.
        //开始构建注入方法的原型:public void inject(Object target)
        //定义注入方法inject的参数和名称:Object是参数类型,target是参数名称
        ParameterSpec objectParamSpec = ParameterSpec.builder(TypeName.OBJECT, "target").build();

        if (MapUtils.isNotEmpty(parentAndChild)) {
            //如果autowrited关系表不为空
            for (Map.Entry> entry : parentAndChild.entrySet()) {
                //遍历autowrited关系表
                // Build method : 'inject'
                //创建注入方法inject的Builder,方法名称是inject,参数是前面创建的:参数类型为Object,参数名称为targe
                MethodSpec.Builder injectMethodBuilder = MethodSpec.methodBuilder(METHOD_INJECT) //方法名
                        .addAnnotation(Override.class) //重写
                        .addModifiers(PUBLIC) //public
                        .addParameter(objectParamSpec); //方法参数及参数名称
                //包含@Autowrited注解的元素,如Activity、fragment
                TypeElement parent = entry.getKey();
                //类中包含被@Autowrited注解的元素列表
                List childs = entry.getValue();
                
                //获取该类的全限定名
                String qualifiedName = parent.getQualifiedName().toString();
                //获取该类的包名
                String packageName = qualifiedName.substring(0, qualifiedName.lastIndexOf("."));
                //定义该类对应的依赖注入类的文件名(即生成的类名)
                String fileName = parent.getSimpleName() + NAME_OF_AUTOWIRED;

                logger.info(">>> Start process " + childs.size() + " field in " + parent.getSimpleName() + " ... <<<");
                //生成要生成的类的Builder
                TypeSpec.Builder helper = TypeSpec.classBuilder(fileName) //类名
                        .addJavadoc(WARNING_TIPS) 
                        .addSuperinterface(ClassName.get(type_ISyringe)) //实现的注射器ISyringe接口
                        .addModifiers(PUBLIC); //public访问权限
                //定义生成中中的字段:private SerializationService serializationService;
                FieldSpec jsonServiceField = FieldSpec.builder(TypeName.get(type_JsonService.asType()), "serializationService", Modifier.PRIVATE).build();
                helper.addField(jsonServiceField);
                //添加类中注入方法inject的内容:serializationService  = ARouter.getInstance().navigation(SerializationService.class)
                injectMethodBuilder.addStatement("serializationService = $T.getInstance().navigation($T.class)", ARouterClass, ClassName.get(type_JsonService));
               //添加类中注入方法inject的内容:xxxActivity/xxxFragment substitute  = (xxxActivity/xxxFragment) target;
                injectMethodBuilder.addStatement("$T substitute = ($T)target", ClassName.get(parent), ClassName.get(parent));

                // Generate method body, start inject.
               //生成注入方法inject的主体,并开始实现注入
                for (Element element : childs) {
                    //遍历类中被@Autowrited注解的元素
                    //获取元素的注解信息对象
                    Autowired fieldConfig = element.getAnnotation(Autowired.class);
                    //获取元素的名称
                    String fieldName = element.getSimpleName().toString();
                    if (types.isSubtype(element.asType(), iProvider)) {  // It's provider
                        //如果元素是Provider类型,则:
                        if ("".equals(fieldConfig.name())) {    // User has not set service path, then use byType.
                            //该元素被@Autowrited修饰时,没有指定name,则:
                            // Getter
                            //添加类中注入方法inject的内容:substitute.fieldName = Arouter.getInstance().navigation(ProviderXXX.class);
                            injectMethodBuilder.addStatement(
                                    "substitute." + fieldName + " = $T.getInstance().navigation($T.class)",
                                    ARouterClass,
                                    ClassName.get(element.asType())
                            );
                        } else {    // use byName
                            // Getter
                            //添加类中注入方法inject的内容:substitute.fieldName = Arouter.getInstance().navigation(@Autowrited.name);
                            injectMethodBuilder.addStatement(
                                    "substitute." + fieldName + " = ($T)$T.getInstance().build($S).navigation()",
                                    ClassName.get(element.asType()),
                                    ARouterClass,
                                    fieldConfig.name()
                            );
                        }

                        // Validator
                        if (fieldConfig.required()) {
                            //如果@Autowrited修饰的元素不能为空,则在inject方法中加上为空则抛出异常:
                            injectMethodBuilder.beginControlFlow("if (substitute." + fieldName + " == null)");
                            injectMethodBuilder.addStatement(
                                    "throw new RuntimeException(\"The field '" + fieldName + "' is null, in class '\" + $T.class.getName() + \"!\")", ClassName.get(parent));
                            injectMethodBuilder.endControlFlow();
                        }
                    } else {    // It's normal intent value
                        //元素类型不是Provider,则代表是intent类型的值
                        //获取元素原始值语句
                        String originalValue = "substitute." + fieldName;
                        //生成注入赋值语句:substitute.fieldName  = (ElementType) substitute.
                        // or 生成注入赋值语句:substitute.fieldName  = substitute.
                        String statement = "substitute." + fieldName + " = " + buildCastCode(element) + "substitute.";
                        boolean isActivity = false;
                        if (types.isSubtype(parent.asType(), activityTm)) {  // Activity, then use getIntent()
                            //该类是Activity的子类,则:
                            isActivity = true;
                            //继续构建注入赋值语句:substitute.fieldName  = substitute.getIntent().
                            statement += "getIntent().";
                        } else if (types.isSubtype(parent.asType(), fragmentTm) || types.isSubtype(parent.asType(), fragmentTmV4)) {   // Fragment, then use getArguments()
                           //该类是Fragment的子类,则:
                             //继续构建注入赋值语句:substitute.fieldName  = substitute.getArguments().
                            statement += "getArguments().";
                        } else {
                            //如果@Autowrited修饰的不是Activity、Fragment则抛出异常
                            throw new IllegalAccessException("The field [" + fieldName + "] need autowired from intent, its parent must be activity or fragment!");
                        }
                        //继续构建注入赋值语句:substitute.fieldName  = [(ElementType)]substitute.[getIntent() | getArguments()].getXXX[Extra](xxx,[originalValue ])
                        statement = buildStatement(originalValue, statement, typeUtils.typeExchange(element), isActivity, isKtClass(parent));
                        if (statement.startsWith("serializationService.")) {   // Not mortals
                            //如果注入赋值语句是序列化serializationService语句,则:
                            //注入方法继续加语句: 如果序列化之后serializationService不为空,则继续完成序列化赋值语句
                            injectMethodBuilder.beginControlFlow("if (null != serializationService)");
                            injectMethodBuilder.addStatement(
                                    "substitute." + fieldName + " = " + statement,
                                    (StringUtils.isEmpty(fieldConfig.name()) ? fieldName : fieldConfig.name()),
                                    ClassName.get(element.asType())
                            );
                            //如果序列化之后serializationService为空,则注入方法中加入日志打印语句
                            injectMethodBuilder.nextControlFlow("else");
                            injectMethodBuilder.addStatement(
                                    "$T.e(\"" + Consts.TAG + "\", \"You want automatic inject the field '" + fieldName + "' in class '$T' , then you should implement 'SerializationService' to support object auto inject!\")", AndroidLog, ClassName.get(parent));
                            injectMethodBuilder.endControlFlow();
                        } else {
                            injectMethodBuilder.addStatement(statement, StringUtils.isEmpty(fieldConfig.name()) ? fieldName : fieldConfig.name());
                        }

                        // Validator
                        if (fieldConfig.required() && !element.asType().getKind().isPrimitive()) {  // Primitive wont be check.
                            //如果@Autowrited注解修饰的元素不允许为空,且不是基本类型,则:
                            //注入方法中加入语句:判断元素如果为空则抛出异常
                            injectMethodBuilder.beginControlFlow("if (null == substitute." + fieldName + ")");
                            injectMethodBuilder.addStatement(
                                    "$T.e(\"" + Consts.TAG + "\", \"The field '" + fieldName + "' is null, in class '\" + $T.class.getName() + \"!\")", AndroidLog, ClassName.get(parent));
                            injectMethodBuilder.endControlFlow();
                        }
                    }
                }
               //工具类添加注入方法
                helper.addMethod(injectMethodBuilder.build());

                // Generate autowire helper
                //使用javapoet结合文件生成工具mFiler生成注入工具类
                JavaFile.builder(packageName, helper.build()).build().writeTo(mFiler);

                logger.info(">>> " + parent.getSimpleName() + " has been processed, " + fileName + " has been generated. <<<");
            }

            logger.info(">>> Autowired processor stop. <<<");
        }
    }

    private boolean isKtClass(Element element) {
        //判断是否是Kotlin类
        for (AnnotationMirror annotationMirror : elementUtils.getAllAnnotationMirrors(element)) {
            if (annotationMirror.getAnnotationType().toString().contains("kotlin")) {
                return true;
            }
        }

        return false;
    }

    private String buildCastCode(Element element) {
        if (typeUtils.typeExchange(element) == TypeKind.SERIALIZABLE.ordinal()) {
            //判断是否是序列化类型,如果是需要添加类型转换语句
            return CodeBlock.builder().add("($T) ", ClassName.get(element.asType())).build().toString();
        }
        return "";
    }

    /**
     * Build param inject statement
     */
    private String buildStatement(String originalValue, String statement, int type, boolean isActivity, boolean isKt) {
        //完成注入负责语句,其实就是生成activity.getIntent().getXXXExtra的赋值语句或者fragment.getArguments().getXXX
        switch (TypeKind.values()[type]) {
            case BOOLEAN:
                statement += "getBoolean" + (isActivity ? "Extra" : "") + "($S, " + originalValue + ")";
                break;
            case BYTE:
                statement += "getByte" + (isActivity ? "Extra" : "") + "($S, " + originalValue + ")";
                break;
            case SHORT:
                statement += "getShort" + (isActivity ? "Extra" : "") + "($S, " + originalValue + ")";
                break;
            case INT:
                statement += "getInt" + (isActivity ? "Extra" : "") + "($S, " + originalValue + ")";
                break;
            case LONG:
                statement += "getLong" + (isActivity ? "Extra" : "") + "($S, " + originalValue + ")";
                break;
            case CHAR:
                statement += "getChar" + (isActivity ? "Extra" : "") + "($S, " + originalValue + ")";
                break;
            case FLOAT:
                statement += "getFloat" + (isActivity ? "Extra" : "") + "($S, " + originalValue + ")";
                break;
            case DOUBLE:
                statement += "getDouble" + (isActivity ? "Extra" : "") + "($S, " + originalValue + ")";
                break;
            case STRING:
                statement += (isActivity ? ("getExtras() == null ? " + originalValue + " : substitute.getIntent().getExtras().getString($S") : ("getString($S")) + ", " + originalValue + ")";
                break;
            case SERIALIZABLE:
                statement += (isActivity ? ("getSerializableExtra($S)") : ("getSerializable($S)"));
                break;
            case PARCELABLE:
                statement += (isActivity ? ("getParcelableExtra($S)") : ("getParcelable($S)"));
                break;
            case OBJECT:
                statement = "serializationService.parseObject(substitute." + (isActivity ? "getIntent()." : "getArguments().") + (isActivity ? "getStringExtra($S)" : "getString($S)") + ", new " + TYPE_WRAPPER + "<$T>(){}.getType())";
                break;
        }

        return statement;
    }

    /**
     * Categories field, find his papa.
     *
     * @param elements Field need autowired
     */
    private void categories(Set elements) throws IllegalAccessException {
        //对被@Autowrited注解修饰的元素进行分类
        if (CollectionUtils.isNotEmpty(elements)) {
            //如果存在被@Autowrited注解修饰的元素
            for (Element element : elements) {
                //遍历被@Autowrited注解修饰的元素列表
                //从被@Autowrited注解修饰的元素element取其父类,如Activity、framgment等
                TypeElement enclosingElement = (TypeElement) element.getEnclosingElement();

                if (element.getModifiers().contains(Modifier.PRIVATE)) {
                    //如果@Autowrited注解修饰的元素是私有字段,则抛出异常
                    throw new IllegalAccessException("The inject fields CAN NOT BE 'private'!!! please check field ["
                            + element.getSimpleName() + "] in class [" + enclosingElement.getQualifiedName() + "]");
                }

                if (parentAndChild.containsKey(enclosingElement)) { // Has categries
                    //如果autowrited关系表中已经存在此父类,则
                    //将被@Autowrited注解修饰的元素加入autowrited关系表
                    parentAndChild.get(enclosingElement).add(element);
                } else {
                    //如果autowrited关系表中不存在此父类,则
                    //创建此父类中被@Autowrited注解修饰的元素列表
                    List childs = new ArrayList<>();
                    //将被@Autowrited注解修饰的元素加入列表中
                    childs.add(element);
                    //autowrited关系表加入类与@Autowrited修饰的元素列表
                    parentAndChild.put(enclosingElement, childs);
                }
            }

            logger.info("categories finished.");
        }
    }
}

根据上述对@Autowrited源码分析,我们可以得出以下结论:
1、@Autowrited修饰Activity、android.app.Fragment、android.support.v4.app.Fragment中的字段
2、@Autowrited实现依赖注入的原理其实就是在编译时生成对应的一个工具类,Activity、Fragment调用inject方法时,其实就是调用该类对应工具类的inject方法,然后实现从getIntent或者getArguments获取对应的值赋值给字段
3、每个Activity、Fragment子类中需要使用@Autowrited进行依赖注入的,都会在编译期自动生成一个该类的一个辅助类,用于实现依赖注入
4、AutoProcessor注解处理器生成依赖注入辅助类的流程是:
4.1、从编译环境中读取所有被@Autowrited注解修饰的元素
4.2、对被@Autowrited注解修饰的元素进行归来,生成autowrited关系表,key是使用了@Autowrited注解的真实类的类型元素对象,value是该类中被被@Autowrited注解修饰的元素列表
4.3、获取ISyringe的类型元素对象,后续生成的辅助类需要实现的接口
4.4、获取序列化服务SerializationService的类型元素,它用于解析json字符串,是操作对象、列表、map等数据的处理类
4.5、获取IProvider、Activity、Fragment的类型信息对象
4.6、创建辅助类中inject方法的参数及名称:Object target
4.7、遍历autowrited关系表:
4.7.1、生成注入方法inject并创建辅助类helper,类名为:xxxActivity/FragmentAutowired
4.7.2、遍历每个类中被@Autowrited修饰的元素
4.7.2.1、在辅助类的inject方法中为每个元素生成赋值语句(值中Activity的getIntent获取或者从Fragement的getArguments获取)
4.7.3、将方法inject加入辅助类helper中,结合文件生成器mFiler生成此辅助类

InterceptorProcessor

InterceptorProcessor是处理@Interceptor注解的注解处理器。

@AutoService(Processor.class)
@SupportedAnnotationTypes(ANNOTATION_TYPE_INTECEPTOR)
public class InterceptorProcessor extends BaseProcessor {
    //拦截器表,key是拦截器优先级,value是被@Interceptor修饰的元素
    private Map interceptors = new TreeMap<>();
    //拦截器IInterceptor类型信息对象
    private TypeMirror iInterceptor = null;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        //初始化拦截器注解处理器InterceptorProcessor 
        //获取IInterceptor类型信息对象
        iInterceptor = elementUtils.getTypeElement(Consts.IINTERCEPTOR).asType();

        logger.info(">>> InterceptorProcessor init. <<<");
    }

    /**
     * {@inheritDoc}
     *
     * @param annotations
     * @param roundEnv
     */
    @Override
    public boolean process(Set annotations, RoundEnvironment roundEnv) {
        //执行InterceptorProcessor注解处理器处理程序
        if (CollectionUtils.isNotEmpty(annotations)) {
           //如果存在注解
           //从编译环境对象中获取被@Interceptor注解修饰的所有元素
            Set elements = roundEnv.getElementsAnnotatedWith(Interceptor.class);
            try {
                //调用parseInterceptors方法解析被@Interceptor注解修饰的所有元素
                parseInterceptors(elements);
            } catch (Exception e) {
                logger.error(e);
            }
            return true;
        }

        return false;
    }

    /**
     * Parse interceptor.
     *
     * @param elements elements of interceptor.
     */
    private void parseInterceptors(Set elements) throws IOException {
        //解析被@Interceptor注解修饰的所有元素
        if (CollectionUtils.isNotEmpty(elements)) {
            //如果存在被@Interceptor修饰的元素,则:
            logger.info(">>> Found interceptors, size is " + elements.size() + " <<<");

            // Verify and cache, sort incidentally.
            for (Element element : elements) {
                //遍历被@Interceptor注解修饰的元素
                if (verify(element)) {  // Check the interceptor meta
                   //校验@Interceptor注解修饰的元素是否合法,如果合法则:

                    logger.info("A interceptor verify over, its " + element.asType());
                    //获取元素中@Interceptor 的注解对象
                    Interceptor interceptor = element.getAnnotation(Interceptor.class);
                    //从拦截器表中获取与此拦截器的优先级一样的拦截器元素
                    Element lastInterceptor = interceptors.get(interceptor.priority());
                    if (null != lastInterceptor) { // Added, throw exceptions
                        //如果存在优先级一样的拦截器,则抛出异常,编译失败
                        throw new IllegalArgumentException(
                                String.format(Locale.getDefault(), "More than one interceptors use same priority [%d], They are [%s] and [%s].",
                                        interceptor.priority(),
                                        lastInterceptor.getSimpleName(),
                                        element.getSimpleName())
                        );
                    }
                    //表示没有重复优先级的拦截器,则将此元素加入拦截器表中,key是拦截器优先级,value是被@Interceptor修饰的元素
                    interceptors.put(interceptor.priority(), element);
                } else {
                    logger.error("A interceptor verify failed, its " + element.asType());
                }
            }

            // Interface of ARouter.
            //获取Arouter类型元素对象
            TypeElement type_IInterceptor = elementUtils.getTypeElement(IINTERCEPTOR);
            //获取拦截器组接口IInterceptorGroup类型元素对象
            TypeElement type_IInterceptorGroup = elementUtils.getTypeElement(IINTERCEPTOR_GROUP);

            /**
             *  Build input type, format as :
             *
             *  ```Map>```
             */
            //生成拦截器组InterceptorGroup类中的loadInto方法的参数类型:Map>
            ParameterizedTypeName inputMapTypeOfTollgate = ParameterizedTypeName.get(
                    ClassName.get(Map.class),
                    ClassName.get(Integer.class),
                    ParameterizedTypeName.get(
                            ClassName.get(Class.class),
                            WildcardTypeName.subtypeOf(ClassName.get(type_IInterceptor))
                    )
            );

            // Build input param name.
            //生成拦截器组InterceptorGroup类中的loadInto方法的参数类型及名称:Map> interceptors
            ParameterSpec tollgateParamSpec = ParameterSpec.builder(inputMapTypeOfTollgate, "interceptors").build();

            // Build method : 'loadInto'
           //生成拦截器组InterceptorGroup类中的loadInto方法的builder对象,方法参数为:Map> interceptors
            MethodSpec.Builder loadIntoMethodOfTollgateBuilder = MethodSpec.methodBuilder(METHOD_LOAD_INTO)
                    .addAnnotation(Override.class)
                    .addModifiers(PUBLIC)
                    .addParameter(tollgateParamSpec);

            // Generate
            if (null != interceptors && interceptors.size() > 0) {
                //如果拦截器表不为空,则:
                // Build method body
                for (Map.Entry entry : interceptors.entrySet()) {
                    //变量拦截器表
                    //为拦截器组的loadInto方法添加语句,将拦截器加入拦截器表interceptors中,key是拦截器的优先级,value是拦截器实现类的class对象
                    loadIntoMethodOfTollgateBuilder.addStatement("interceptors.put(" + entry.getKey() + ", $T.class)", ClassName.get((TypeElement) entry.getValue()));
                }
            }

            // Write to disk(Write file even interceptors is empty.)
           //使用上述生成的java类及方法信息,结合文件生成器mFiler生成拦截器表类文件,类名为:ARouter$$Interceptors$$moudleName
            JavaFile.builder(PACKAGE_OF_GENERATE_FILE,
                    TypeSpec.classBuilder(NAME_OF_INTERCEPTOR + SEPARATOR + moduleName)
                            .addModifiers(PUBLIC)
                            .addJavadoc(WARNING_TIPS)
                            .addMethod(loadIntoMethodOfTollgateBuilder.build())
                            .addSuperinterface(ClassName.get(type_IInterceptorGroup))
                            .build()
            ).build().writeTo(mFiler);

            logger.info(">>> Interceptor group write over. <<<");
        }
    }

    /**
     * Verify inteceptor meta
     *
     * @param element Interceptor taw type
     * @return verify result
     */
    private boolean verify(Element element) {
        //校验被@Interceptor注解修饰的元素是否合法
        Interceptor interceptor = element.getAnnotation(Interceptor.class);
        // It must be implement the interface IInterceptor and marked with annotation Interceptor.
        //如果元素有@Interceptor注解且元素实现了IInterceptor接口,则合法,否则不合法
        return null != interceptor && ((TypeElement) element).getInterfaces().contains(iInterceptor);
    }
}

根据上述源码解析,我们对拦截器注解处理器得出如下结论:
1、拦截器注解处理器会为每个模块生成一个拦截器表类文件,类名为:ARoutermoudleName
2、拦截器表类实现IInterceptorGroup接口,且其内部也进只有一个loadInto方法,用于向拦截器表中添加本模块内的所有拦截器
3、模块内的拦截器不允许优先级一样的拦截存在
4、@Interceptor只能用于修饰实现了IInterceptor接口
5、注解器生成模块拦截器表类的步骤:
5.1、从编译环境中读取被@Interceptor修饰的所有元素列表
5.2、遍历被@Interceptor修饰的所有元素,过滤模块内优先级重复的拦截器,并把拦截器放入拦截器表中,拦截表key是拦截器的优先级,value是拦截器的元素
5.3、生成模块模块拦截器表类实现的loadInto方法Builder及方法参数对象:Map> interceptors
5.4、遍历拦截器表
5.4.1、为本模块拦截器表类中loadInto方法添加语句:interceptors.put(interceptorPriority, interceptor.class),即把模块内的拦截器的class加入全局拦截器表中
5.5、使用生成的拦截器表类的方法,结合文件生成器mFiler生成本模块的拦截器组类,类名为:ARoutermoudleName

你可能感兴趣的:(Arouter之注解处理器)