java – 反射与注解小练手

JAVA生态的开源项目大量使用反射,并且随处可见注解,如果不懂基础就照葫芦画瓢的确让人很不舒服。

下面我将利用注解和反射,实现一个简单的Web路由(类似spring mvc的感觉)示例:即在处理函数上利用注解配置URI映射,并自动的根据请求的URI调用对应的处理函数。

完整代码:https://github.com/owenliang/java-somewhat/tree/master/src/cc/yuerblog/annotation

定义注解

通过@interface可以定义注解类Uri。

该注解使用的时候可以接收1个参数叫做path,用于声明哪个方法用于处理哪个URI的请求,稍等下面我们会看到使用示例。

Target元注解声明Uri注解只能用在类的方法上,ElementType也支持指定为类的注解、用于参数的注解、用于私有变量的注解等等。

Retention元注解声明Uri注解是运行时的,也就是说JVM运行我们程序的时候,我们可以通过反射机制拿到Uri注解的详细信息,比如获取其中的path()参数。

还是有点抽象,所以下面先说怎么用Uri。

使用注解

App类相当于Controller,用于处理HTTP请求。

有2个方法:

  • getUserInfo方法:指定path匹配/user/{username}/info这样的URI,其中{username}的花括号表示捕获URI中该位置的值,作为String username参数传给方法。
  • getProductInfo方法:一样的道理,不过捕获的productID要作为int类型传参给getProductInfo方法。

接下来,我要实现路由逻辑,根据URI找到对应的方法并调用。

匹配路由

首先创建App对象,测试2个URI的路由结果。

handleRoute负责具体路由逻辑:

  • 拆分URI:将请求的URI按/拆分成数组,这是为了后续与@Uri注解中的path高效匹配。
  • 遍历所有方法:反射App类得到所有method,并进一步获取每个method上的Uri类的注解对象,
    • 如果method应用了Uri注解,那么得到其path值,按/拆分成数组,并且与Uri进行匹配判定。
    • 如果path某个部分是{xxx}的捕获语法,那么将其对应URI中的值捕获下来,作为后续调用method的传参,注意捕获的都是String。

调用方法

一旦确认path和URI完全匹配,那么就要最终调用该method了。

所以接下来做的事情是:

  • 反射参数:getParameters()获取待调用method的所有参数信息,
    • 确认参数个数和之前捕获的参数值个数相同。
    • 遍历每个参数信息,根据其类型决定如何对捕获的值字符串进行类型转换:
      • 参数是int,那么通过parseInt将捕获字符串变成Integer。
      • 参数是String,那么原样传递。
    • 最后,将准备好的参数值列表作为method的参数,通过invoke传入app对象与参数列表,就可以完成调用了。

程序输出:

查找用户:owenliang
查找商品:110

全文结束。

如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~