被迫尝试了各个版本的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
目录
相关文章
|
9月前
|
Java
[ASM教程]#1分析类
ASM是一种通用Java字节码操作和分析框架,它可以用于修改现有的class文件或动态生成class文件。
73 0
|
9月前
[ASM教程]#2生成类
使用classWriter生成类
36 0
|
设计模式
访问者设计模式(Visitor)的生动案例-ASM字节码修改库
访问者设计模式(Visitor)的生动案例-ASM字节码修改库
106 0
|
Java
ASM 库的 classVisitor 类解析
ASM 库的 classVisitor 类解析
412 0
|
Java 索引
Java字节码修改库ASM#ClassReader实现原理及源码分析(下)
Java字节码修改库ASM#ClassReader实现原理及源码分析(下)
276 0
|
Java 索引
Java字节码修改库ASM#ClassReader实现原理及源码分析(上)
Java字节码修改库ASM#ClassReader实现原理及源码分析(上)
314 0
Java字节码修改库ASM#ClassReader实现原理及源码分析(上)
|
Oracle 关系型数据库 安全
|
Java Spring SQL
ASM + 接口 动态生成类
好吧 ,我承认上篇文章 确认让人看不明白ASM到底有什么用,那么这篇来举个例子吧 ,比如 我制定任意的接口(接口名称,接口方法都是随意的) package com.
776 0