被迫尝试了各个版本的asm库读取类annotation-阿里云开发者社区

开发者社区> 开发与运维> 正文

被迫尝试了各个版本的asm库读取类annotation

简介: 杯具的写完代码才发现应用原来依赖的cglib使用了1.x的asm库,从最初使用3.x版本到2.x,然后使用1.x才搞定asm的兼容性。这里记录下不同版本如何读取annotation。 asm3.2: 这个版本非常方便,实现ClassVisitor接口,里面有个visitAnnotation方法,

杯具的写完代码才发现应用原来依赖的cglib使用了1.x的asm库,从最初使用3.x版本到2.x,然后使用1.x才搞定asm的兼容性。这里记录下不同版本如何读取annotation。

asm3.2:
这个版本非常方便,实现ClassVisitor接口,里面有个visitAnnotation方法,方法签名是: AnnotationVisitor visitAnnotation(String desc, boolean visible) ,其中desc是annotation的类型(Lxxx/xxx/xxx;),稍微处理下就可以将java byte code的表示形式变成Annotation的类名;visible表示该annotation是否运行时可见,因为我需要类加载后读取annotation的值,可以通过这个参数来判断。因为我只是用来获取annotation的名字,不需要读取annotation里面的key和value,所以直接返回null就可以了。如果要继续深入解析这个annotation,可以通过实现AnnotationVisitor接口并返回来解析。
asm2.2:
降到了这个版本,是运行时cglib库提示ClassWriter没有传入boolean参数的构造函数,这个应该算是asm升级到3.x之后没有做到向下兼容的一个地方。降级到asm2.2,修改的地方很少,就是ClassReader的accept函数,是否跳过debug信息标签,从int型的flag变成了个boolean型。读取annotation的方法没有变化。
asm1.5.3:
改用了2.2之后,还有运行时错误,木有找到CodeVisitor。只能降级到1.5.3了。降级到这个版本修改上面读取annotation的代码成本还是比较高的,这个版本里面ClassVisitor没有了visitAnnotation这个函数,而是把annotation当成了一个Attribute,所以只能通过visitAttribute函数。不过反而这个版本读取annotation官方有个文档:http://asm.ow2.org/doc/tutorial-annotations.html
当然我不需要这么复杂做动态代理什么的,只是读取annotation的名字。大体上就是,先通过visitAttribute函数,判断当前传入的Attribute是否是RuntimeVisibleAnnotations的实例,如果是就能够获取里面的公有变量annotations(类型是List<Annotation>)。我所需要的annotation名字,就在Annotation对象的type字段。这里的type也是bytecode中的类表示方法,如果需要获取能够直接被Class识别的类名,可以自己做简单的字符串处理,或者:
String type = annotation.type;
Type t = Type.getType(type);
String cname = t.getClassName();
这样来拿到className。
这次对向下兼容深有体会啊~~

转载自:https://coolex.info/blog/192.html

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章