使用 cglib_五、cglib及asm

五、cglib及asm

spring的aop功能生成的代理类使用的cglib,cglib的底层实现是asm。

我们先分析下cglib,编写cglib代理时,最主要的就是编写Callback接口实现类,我们时常编写的实现类实现接口MethodInterceptor,该接口也是继承了Callback接口。实现了MehthodInterceptor接口之后,需要实现invoke方法。这样就可以使用cglib代理类了。

我认为如果我们真的要生成一个类,可能只会用到ClassWriter、MethodVisitor,ClassReader、ClassVisitor可能用不到。用ClassReader结合ClassWriter的时候很坑,总会生成2个方法。用ClassWriter可能会好点,但是属性、字段、方法都要自己去生成,工作量会大点。

用ClassReader结合ClassWriter的时候,类的方法、属性都带过来了,可能要写个adapter,对reader的事件进行过滤,比如访问到某个方法的时候,就把这个方法移除掉。

对应asm呢?如果我们要修改一个类的方法,那么就首先用到ClassWriter visit访问这个类,然后用MethodVisitor去改造这个方法。那么如何简单去用asm代码去改造一个类呢?

比如我们有一个已经编写好的类Programmer:

a6cfabde739e7f32ba64fa9896e465a3.png

我们需要改造成如下,修改它打印的内容:

41592a419186ed66c11b170719518271.png

那么我们最简单的办法是什么呢? 我认为一定不是去直接编写ams代码,而是先把这个改造后的类先用Java代码编写出来,然后进行javap –c去分析这个类,如下:

3193855964ad69419773f6c48877eb0e.png

然后再根据这个反编译的结果去用asm代码编写我们的类,

可以看到,编写的代码跟我们javap指令的结构很相似。这样编写的难度及代码错误率会减少。

还有一种更简单的方法是, 也是自己先编写好类, 然后运行org.objectweb.asm.util. ASMifier, 把自己的全路径下的类作为参数传递过去就OK了。

自己编写asm代码的时候,有很多坑,比如“Ljava/lang/String;”后面少了个分号就不行了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值