ARouter学习之二——注解(arouter-annotation源码)

因为好奇,所以学习。

解决为什么引入ARouter框架后,@Autowired和 @Route等注解可以生效(正常工作),不引入则报错.

注:源码来自2019/09/10 Git下载的版本1.5.0    https://github.com/alibaba/ARouter


目录

目录

目录

一、源码arouter-annotation介绍

二、Java中的注解(Annotation)

三、注解(Annotation)的声明与定义

四、尾声与疑问


一、源码arouter-annotation介绍

作为ARouter的组成Model之一,annotation主要作用是提供了注解、枚举和数据模型。源码结构如下图:

Autowired用于变量传参;Interceptor用于拦截器;Route用于路由。这就是我们为什么会在引用了ARouter的工程中看到如下的代码:

@Route(path = "/test/activity1", name = "测试用 Activity")
public class Test1Activity extends AppCompatActivity {

    @Autowired(desc = "姓名")
    String name = "jack";

    @Autowired
    int age = 10;

    @Autowired(name = "boy", required = true)
    boolean girl;
    
    ...
}

再来看下所谓的枚举,都有哪些,是做什么用的。

public enum RouteType {
    ACTIVITY(0, "android.app.Activity"),
    SERVICE(1, "android.app.Service"),
    PROVIDER(2, "com.alibaba.android.arouter.facade.template.IProvider"),
    CONTENT_PROVIDER(-1, "android.app.ContentProvider"),
    BOARDCAST(-1, ""),
    METHOD(-1, ""),
    FRAGMENT(-1, "android.app.Fragment"),
    UNKNOWN(-1, "Unknown route type");

    int id;
    String className;
}

通过枚举名可以推断,其作用是用来标识ARouter支持哪些类型的跳转。如:Activity、Fragment、Service。

剩下的数据模型应该就是所谓的实体吧,如路由信息实体,就像定义一个学生实体一个,路由的实体应该包含必要的信息字段,源码如下:

public class RouteMeta {
    private RouteType type;         // Type of route
    private Element rawType;        // Raw type of route
    private Class<?> destination;   // Destination
    private String path;            // Path of route
    private String group;           // Group of route
    private int priority = -1;      // The smaller the number, the higher the priority
    private int extra;              // Extra data
    private Map<String, Integer> paramsType;  // Param type
    private String name;

    private Map<String, Autowired> injectConfig;  // Cache inject config.

    ...

}

二、Java中的注解(Annotation)

介绍完ARouter的Annotation整体后,是时候细看下具体的注解源码。以Autowired为例:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * Annotation for field, which need 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 "";
}

源码引入了java.lang.annotation包下的四个文件,而且@Target和@Retention显然也是注解,所以暂时可以忽略它们两个,着重看下ElementType和RetentionPolicy。原因是当弄明白Autowired是如何定义使用的,被忽略的两个注解自然也就懂了。

Java的API是这样描述ElementType的:一组常量的枚举,用来区别Java程序中的不同类别的元素,它通过Target注解来使用,增加对一个注解类型的限制判断。(纯英语四级水平的理解)

意思就是一个Java文件的代码被标识为不同类型的元素,如方法、变量、类、接口、包名等,那么当定义一个注解时,需要声明我们定义的注释是作用于哪种类型元素上的时候,就需要使用@Target注解来声明,限制这个注解的使用场景(发挥作用的元素类型)。那么具体有哪些?API已经列出,好像也不算多:

OK,第一行代码搞定,说明@Autowired的注解是作用于变量(字段)上的。

看一眼@Route的源码,其作用于类、接口上。

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

再来学习RetentionPolicy

说实话,API只看到这里,我仍然是有点晕。只知道也是一组常量,用来声明注解的有效时长(生命周期的概念),看完枚举值才恍然明白,就是所谓的编译时注解和运行时注解,自然编译时注释的时长(生命周期)要长了。

得来,@Autowired和@Route注解均为编译时注解,一个作用于变量字段,一个作用于类和接口。

三、注解(Annotation)的声明与定义

多看几个注解的源码,依葫芦画瓢,大体可以猜出几点:

public @interface Route {
    ...
}

1.内部参数只能用public或默认,不能是private!!

2.参数只能使用基本类型。

3.后面可跟默认值。

4.若注解前被@Inherited注解了,则该声明的注解可在继承中使用。默认注解不支持继承。

四、尾声与疑问

至此,本文章开头的疑问解答了,我们在引用ARouter后所使用的注解是从哪来的,已经不再是问题。

但随之而来的是,为什么定义的这个注解就生效了呢?能帮助我们实现路由跳转呢?或实现参数赋值呢?

这需要去ARouter的compiler模块找下答案——Java注解处理器。下篇见!

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值