Eclipse下Javassist正确使用方法代码解析
作者:三向板砖 时间:2021-07-24 18:43:57
这两天看到Hibernate的代理部分,第一反应是底层使用了反射,针对用户实体生成了代理类,后来反应过来了,反射没有任何可以产生新类的能力,也就顺理成章地找到了Javassist(下载地址)。
在网上搜索到的大部分教程,都是针对Javassist的API进行一番讲解,但是最后,往往没有一个加载过程,而笔者模仿这些教程进行类的加载时,加载到的结果都是原来的类,并没有产生字节码被修改的内容。
在经过一番探索后,笔者发现,网上的大部分教程中的最后一步,保存字节码,使用的均是writeFile的无参数重载,在查看其函数结构后发现,它还有一个String类型的重载,由于在Eclipse下,字节码储存的根位置并不是”.\\”而是”.\\bin”,而writeFile的另一个重载很可能是指定字节码根位置的参数,笔者进行一番更改后发现,果不其然。
下面将演示代码分享出来:
这是笔者项目的结构:
Editable.java:
package com.thrblock.javassist;
public class Editable {
public void showInfo(){
System.out.println("InfoDefault!");
}
}
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。
来源:http://blog.csdn.net/shuzhe66/article/details/39319121
标签:eclipse,javassist
0
投稿
猜你喜欢
基于springboot实现redis分布式锁的方法
2023-06-16 01:36:56
Unity 修改FBX模型动画的操作
2023-03-17 17:59:39
Android开发之DrawerLayout实现抽屉效果
2023-09-30 03:40:59
详解关于SpringBoot的外部化配置使用记录
2023-08-10 03:54:54
图解二叉树的三种遍历方式及java实现代码
2022-02-08 12:03:32
Java特性之注解和异常 Throwable
2023-04-22 13:14:53
java并发分段锁实践代码
2021-10-08 04:55:45
sprng和struts有什么区别?
2022-03-02 02:13:35
详解C++中的指针、数组指针与函数指针
2023-04-11 05:35:24
java 值Document解析xml详细介绍
2021-11-13 15:59:00
spring中使用mybatis plus连接sqlserver的方法实现
2022-11-16 12:05:09
Java中final与继承操作实例分析
2023-09-14 08:56:02
Java8-Stream流操作List去重问题
2023-11-23 23:29:49
C++版本基于ros将文件夹中的图像转换为bag包
2021-11-13 07:15:59
详解C# 匿名对象(匿名类型)、var、动态类型 dynamic
2022-03-26 18:43:02
深入Unix时间戳与C# DateTime时间类型互换的详解
2023-06-04 21:48:11
详解spring-boot actuator(监控)配置和使用
2022-07-12 17:20:37
Jmeter生成UUID作为唯一标识符过程图解
2022-09-17 03:35:36
Android Compose衰减动画Animatable使用详解
2022-08-26 23:09:42
Android 动态菜单实现实例代码
2023-05-19 16:24:58