服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - Eclipse下Javassist正确使用方法代码解析

Eclipse下Javassist正确使用方法代码解析

2021-03-09 13:25三向板砖 Java教程

这篇文章主要介绍了Eclipse下Javassist正确使用方法代码解析,javassist-3.15.0-ga.jar包是一款在java开发中十分重要的jar文件包,需要的朋友可以参考下,文中附下载链接。

这两天看到Hibernate的代理部分,第一反应是底层使用了反射,针对用户实体生成了代理类,后来反应过来了,反射没有任何可以产生新类的能力,也就顺理成章地找到了Javassist

在网上搜索到的大部分教程,都是针对Javassist的API进行一番讲解,但是最后,往往没有一个加载过程,而笔者模仿这些教程进行类的加载时,加载到的结果都是原来的类,并没有产生字节码被修改的内容。

在经过一番探索后,笔者发现,网上的大部分教程中的最后一步,保存字节码,使用的均是writeFile的无参数重载,在查看其函数结构后发现,它还有一个String类型的重载,由于在Eclipse下,字节码储存的根位置并不是”.\\”而是”.\\bin”,而writeFile的另一个重载很可能是指定字节码根位置的参数,笔者进行一番更改后发现,果不其然。

下面将演示代码分享出来:

这是笔者项目的结构:

Eclipse下Javassist正确使用方法代码解析

?
1
2
3
4
5
6
7
8
Editable.java:
package com.thrblock.javassist;
  
public class Editable {
   public void showInfo(){
       System.out.println("InfoDefault!");
   }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Main.java:
package com.thrblock.javassist;
import java.io.IOException;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.NotFoundException;
public class Main {
    public static void main(String[] args) {
        ClassPool pool = ClassPool.getDefault();
        try{
            pool.insertClassPath(".\\bin");
            //设置根路径。(这里设置的根路径显然没被writeFile使用)
            CtClass cc = pool.makeClass("com.thrblock.javassist.EditableChanged");
            //模拟Hibernate代理模式,我们创建一个新类
            cc.setSuperclass(pool.get("com.thrblock.javassist.Editable"));
            //设置其父类
            CtMethodcm = CtNewMethod.make("public void showInfo(){super.showInfo();System.out.println(\"CustomInsertHAHA!\");}",cc);
            //追加一个方法,注意它覆盖了父类中的方法。
            cc.addMethod(cm);
            cc.writeFile(".\\bin");
            //这里比较重要,空参的结果就是没有保存到eclipse字节码根路径里。
        }
        catch (NotFoundException | CannotCompileException | IOException e) {
            e.printStackTrace();
        }
        try{
            Class<?> cl = Class.forName("com.thrblock.javassist.EditableChanged");
            //加载我们的新类
            Editableed = (Editable) cl.newInstance();
            //由于其继承与Editable类,这里和Hibernate里的load道理一样。
            ed.showInfo();
            //调用方法。
        }
        catch (ClassNotFoundException | InstantiationException |IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

打印结果:

InfoDefault!

CustomInsertHAHA!

其他注意事项:

由于我们是生成了一个类,如果这个类名和原类名一样,则会覆盖class文件,但是如果修改之前该class已经被JVM装入,则修改的部分不会生效,必须重启JVM。

总结

以上就是本文关于Eclipse下Javassist正确使用方法代码解析的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

原文链接:http://blog.csdn.net/shuzhe66/article/details/39319121

延伸 · 阅读

精彩推荐