做个笔记,马克一下。
思考
假设有某类ClassA的方法sayHello,在不改动源代码的基础上,想要在每次调用该方法前后各打印一句话,表示开始/结束。
一般情况下,一种容易想到的方法是建立一个代理类ClassAProxy,再适当改改sayHello方法,以后咱就别用ClassA,都用这个代理类得了。
public class ClassAProxy extends ClassA{
@override
public void sayHello() {
System.out.println("before sayHello ...");
super.sayHello();
System.out.println("after sayHello ...");
}
}
这虽然不是动态的,但朴素的动态代理也就这个思路没跑了。
但这并不是最优解。因为JVM底层存在字节码层面修改操作的可能,想要实现目标,可以想办法在sayHello方法对应的字节码前后注入相应操作,再替代原有方法。
先不管细枝末节,实现难度什么的。相比于朴素的想法,这样毫无疑问减少了开销,性能上会得到提升。
再来看看细枝末节,如果单纯看编译时生成后的Java 字节码,显然与Java语言本身有很大区别,乍一看肯定会卧槽卧槽卧槽。我都不熟悉还改个麻花。。。
- 所以现在就有两(?)个选择了:
- A. 吃透JVM指令什么的,至少是需要的那一部分;
- B. 哈哈,有现成的工具,在源码级别可以定义,不需要学习JVM指令,棒棒哒 ;
- C. 介于AB之间
这大概就是Java字节码操作的现状了吧~~~
另外,记几个关键词:BCEL
、ASM
、CGLIB
、Javassist