Rayson API 框架分析系列之7: 注解处理器(APT)原理

本系列之1: 简介
本系列之2: API服务开发
本系列之3: RSON序列化格式
本系列之4: RPC调度原理
本系列之5: NIO实现原理
本系列之6: 客户端动态代理原理
本系列之7: 注解处理器(APT)原理👈

本文介绍Rayson框架使用APT(Annotation-Processing-Tool )来抽取API元数据的原理.

概述

前文曾经讲过,Rayson框架使用Java接口定义API协议,如下面例子定义了一个API协议:

@Service
public interface SimpleProtocol extends Protocol {
    /**
     * Echo received message.
     * 
     * @param msg The message to be echo.
     * @return Return the given message.
     */
    @TestAnnotation("test annotaiton")
    public String echo(String msg) throws IOException, RpcException;

    /**
     * Echo received message.
     * 
     * @param msg The message to be echo.
     * @return Return the given message.
     */
    public byte[] echo2(byte[] msg) throws IOException, RpcException;
}

我们知道,Java的接口被编译成class文件时候,方法(Method)参数的名字默认是丢失掉的。如上面的方法#echo(String msg),在编程成class的时候,唯一参数的名字msg就被擦除了。这样就导致Rayson框架无法识别协议所定义的API的参数名。

为了弥补这个问题,Rayson框架使用了Java的APT(Annotation Processing Tool)来在编译时对API协议进行预处理。
因为APT只能处理添加特定注解的Java类,因此接口SimpleProtocol添加了注解@org.rayson.api.annotation.Service,来告知APT需要处理这个接口。

Rayson APT 放在rayson.api库中,开发者只需要在API开发项目中引入了该库,就能在使用javac编译项目的时候对定义API协议的Java接口执行Rayson APT的预处理。

最后,Rayson APT对于Rayson框架来说是可选的,也就是说开发者定义的API协议,即使没有经过Rayson APT的处理仍然是可以工作的。不过这种情况下就会缺少API协议的元数据,使得开发出来的API有一定的使用限制,例如只能使用动态参数名来调用API。

预处理过程

下面我们以上文的示例协议为例,说明Rayson APT所做的预处理。

  • 为方法参数添加注解来为参数添加运行时的名称。
    上文的接口经过这一步骤的处理,其源代码相当于下面代码所示:
@Service
public interface SimpleProtocol extends Protocol {
    @TestAnnotation("test annotaiton")
    public String echo(@SerializedName("msg") String msg) throws IOException, RpcException;
    public byte[] echo2(@SerializedName("msg") byte[] msg) throws IOException, RpcException;
}

其中,注解@org.rayson.api.annotation.SerializedName被自动添加于每个方法参数,用来为参数指定运行时名称。

  • 生成JSON格式的描述文件,用于存储协议的元数据。Rayson框架会在启动服务时候加载这些元数据。
    上文的接口,经过这一步骤的处理,会在跟编译后Java类所在的同一目录下,生成一个文件SimpleProtocol$rayson$proto.json,其内容如下所示:
{
   "version": "1.0",
    "name": "org.rayson.demo.simple.api.SimpleProtocol",
    "comment": "",
    "methods": [
        {
            "name": "echo2",
            "comment": " @return Return the given message.\r\n",
            "returnType": "byte[]",
            "returnComment": null,
            "annotations": [
            ],
            "parameters": [
                {
                    "name": "msg",
                    "index": 0,
                    "comment": null
                }
            ]
        },
        {
            "name": "echo",
            "comment": " @return Return the given message.\r\n",
            "returnType": "java.lang.String",
            "returnComment": null,
            "annotations": [
                "@org.rayson.demo.simple.api.TestAnnotation(\"test annotaiton\")"
            ],
            "parameters": [
                {
                    "name": "msg",
                    "index": 0,
                    "comment": null
                }
            ]
        }
    ]
}
  • 拷贝协议接口的Java源代码文件,跟编译后的Java类放在同一目录下。这些源代码会被Rayson作为API服务的定义文件使用。

代码原理

Rayson APT主要使用了JAVA的APT来实现,其源代码放在Rayson的子项目rayson.api中的org.rayson.apt包下,其代码原理在此不再赘述,请参考Rayson APT源代码

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值