字节码增强总结

经常遇见字节码就懵逼,ASM, CGLIB, Instrument, Aspect, Spring AOP这些都是啥关系,有什么作用。今天就让我们来试着总结一下。

一切还要从Instrument讲起

Instrument是JVM提供的一个可以修改已加载类的类库,专门为Java语言编写的插桩服务提供支持。在JDK 1.6以前,instrument只能在JVM刚启动类时生效,而在JDK 1.6之后,instrument支持在运行时对类定义的修改。

我们看一下instrument的类库都包括什么:

Instrumentation
ClassFileTransformer

非常简单,再查看Instrumentation内容,可以发现它的主要作用是addClassFileTransformerremoveClassFileTransformer

而ClassFieldTransformer的内容就更简单了。

byte[]
  transform(  ClassLoader         loader,
            String              className,
            Class<?>            classBeingRedefined,
            ProtectionDomain    protectionDomain,
            byte[]              classfileBuffer)
  throws IllegalClassFormatException;

只有一个方法,就是对classname的类进行转换,返回新的byte字节码。

看到这里,相信我们已经很明显的确定了一件事情: 别管什么字节码增强技术,都得经过instrument官方这条路。这个并不准确,我们最后会进行总结。

字节码操作技术

我们应该都记得Java的咖啡☕️的由来,就是因为字节码开头是CAFE BABE这个魔数,之后就是一些十六进制的数字了,那如果让我们手动来修改这些数字,相信是个人都会很头大。所以这就有了字节操作技术,也就是我们常常听到的ASM, javassit。为什么会有一系列的

字节码操作技术呢? 这里不妨上一下字节码操作技术的区别。

技术特点实例
Javassist很轻量级,只有700kb左右,无需了解Class文件的结构,简单易学一些rpc框架会采用
Asm需要比较了解Class文件结构,特性比较完整Cglib,Lombok
BcelAPI比较原子化,需要对java instruction集合比较熟悉AspectJWeaver
cglib容易学习,仅需要少量的字节码只是

比较来源: [Dynamic Java Bytecode Manipulation Framework Comparison](https://stackoverflow.com/questions/9167436/dynamic-java-bytecode-manipulation-framework-comparison)

从这些比较来看,主要还是面向的问题空间不同,所以就产生了不同的解决方案空间。

代理

字节码增强和代理经常是混合在一起,那么他们之间的关系是什么?

代理的定义是: 简单来说,代理是一个存在客户端和调用对象之间的物体,它可以做到简单的转发,也可以提供一些额外的逻辑。

In short, a proxy is a wrapper or agent object that is being called by the client to access the real serving object behind the scenes. Use of the proxy can simply be forwarding to the real object, or can provide additional logic.

从这个定义上来看,代理是为了在实际调用增加逻辑的手段。字节码增强当然能做到这个事情,比如我们刚才提到的AspectJWeaver通过字节码可以直接将对应的代码织入对应的方法,那么Apsectj算是代理吗? 我这里小声儿地说,严格来说并不算…

那么大家经常动态代理的两大人柱力: proxy、cglib,和AspectJ有什么区别呢?

proxy和cglib主要的方式是生成新的类,来提供proxy服务,这就比较符合proxy的定义了。

为什么Spring引用AspectJ,但经常说我们的动态代理是cglib呢?

首先,从时间发展上看,AspectJ和Spring一开始没有很大的关系,但是AspectJ由于比较活跃形成了AOP的规范,所以Spring就采用了它的规范。

其次,Aspect的方式是它自己的代码增强,可以完全不依赖于Spring。但Spring在使用的时候,并没有使用,而是通过自己的代理去生成。有兴趣的同学可以看一下@EnableAspectJAutoProxy注解生效的过程。

总结

在这里插入图片描述

  1. 字节码增强包括两部分: instrument类库 + 字节码操作(ByteManipulation)

  2. AOP的实现方式可以基于字节码增强原始类,也可以生成新的类进行实现

  3. wiki: AspectJ

  4. 字节码增强技术探索

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值