NiceLeeのBlog 用爱发电 bilibili~

Java 动态代理与字节码

2019-11-08
nIceLee

阅读:


做个笔记,马克一下。

思考

假设有某类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字节码操作的现状了吧~~~

另外,记几个关键词:BCELASMCGLIBJavassist


内容
隐藏