result: 1 2 2、getDeclaredField getDecalaredField是java.lang.Class中的一个方法,该方法返回一个Field对象,它反映此Class对象所表示的类或接口的指定已声明字段...下面大概讲一下POC中会用到的类和方法: 5.2 ClassPool ClassPool是CtClass对象的容器,它按需读取类文件来构造CtClass对象,并且保存CtClass对象以便以后使用,其中键名是类名称...; ClassPath appendClassPath 将一个ClassPath对象加到类搜索路径的末尾位置; CtClass makeClass 根据类名创建新的CtClass对象; CtClass...CtClass对象都必须从ClassPool中获取。...常用方法 解释 void setSuperclass(CtClass clazz) 更改超类,除非此对象表示接口; byte[] toBytecode() 将该类转换为类文件; CtConstructor
因此,为了正确编译这样的方法调用,ClassPool必须包含程序执行时所有的CtClass实例。...// 首先获取表示Point类的一个CtClass对象 // 然后调用setName修改类名 ClassPool pool3 = ClassPool.getDefault(); CtClass cc3...setName()方法为CtClass对象设置新的名称。...因此,如果代表Point类的CtClass对象冻结后不能通过setName()修改它的名称。...{ // 获取一个新的CtClass对象 CtClass clazz = get0(orgName, false); if (clazz == null) throw
---- Javassist作用 运行时监控插桩埋点 AOP动态代理实现(性能上比Cglib生成的要慢) 获取访问类结构信息:如获取参数名称信息 ---- 常用API 类 说明 ClassPool Javassist...的类池,使用ClassPool 类可以跟踪和控制所操作的类, 与 JVM ClassLoader相似 CtClass CtClass提供了类的操作,如在类中动态添加新字段、方法和构造函数、以及改变类、父类和接口的方法...CtClass returnType = pool.get(void.class.getName()); // 方法名称 String mname = "sayHello...CtClass ctClass = classPool.get("com.artisan.agent.UserService"); // 获取方法 CtMethod...动态修改的类,必须在修改之前,jvm中不存在这个类的实例对象。
ClassPool: 一个基于Hashtable实现的CtClass对象容器, 其中键是类名称, 值是表示该类的CtClass 对象....(true) 一致 ClassPool pool1 = ClassPool.getDefault(); 3.2 类对象 3.2.1 获取类对象 // 通过类名获取 CtClass, 未找到会抛出异常...CtClass ctClass = pool.get("test.DemoService"); // 通过类名获取 CtClass, 未找到返回 null, 不会抛出异常 CtClass ctClass1...Ljava/lang/String;Ljava/util/List;Lcom/test/Order;)Ljava/lang/Integer; ctMethod.getSignature(); // 获取方法参数名称...插入的代码片段必须以throw或return语句结束 CtMethod m = ...; CtClass etype = ClassPool.getDefault().get("java.io.IOException
好了,我们今天就使用Javassist动态生成一个HelloWorld案例,可以直接到Github和Gitee获取。...public class GenerateHelloWorldClass { /** * 创建HelloWorld的类,并返回HelloWorld的Class实例 */...(ctMethod); //将生成的类的class文件输出的磁盘 ctClass.writeFile(); //返回HelloWorld的Class实例...(3) 给类添加方法,并设置方法的返回类型、方法名称、参数名(入参和出参)、访问修饰符以及方法体。...(7) 在main()方法中调用createHelloWorld()方法获取Class对象。 (8) 通过反射实例化对象,并通过反射调用生成的HelloWorld类的main()方法。
为了修改一个类的定义,用户必须首先从ClassPool对象的.get(className)方法获取一个CtClass引用。...从ClassPool中获取到的CtClass对象是可以被修改的。...当一个CtClass对象被修剪后,方法的字节码则不能被访问除了方法名称、方法签名和注解。修剪过的CtClass对象不会被解冻。默认修剪值是false。...你也可以注册一个目录的名称作为一个class查找路径。...ctClass = pool2.get(name); CtClass对象ctClass表示字节数组b指定的class文件定义的类实例。
后来有一天就想着,能不能开发一个适配性Json的Interceptor,在配置文件中配置字段名称,就自动生成实体类,然后自动在Gson中引入这个实体类,对json数据进行解析。...接着就是看看如何都创建CtClass对象。从注释中看,CtClass是从ClassPool中获取。...(ctClass);我们来获取String的CtClass。...Flume主要是从外部配置参数,然后通过脚本启动,所以我将json实体类的字段名称都通过参数配置。日常开发中比较常见的json主要有两种格式:简单类型,都是一个字段对应着一个简单类型。...如何能通过CtClass获取到Class,这里肯定首先想到类加载器ClassLoader,在Class源码注释中,也提供了这个方法。
读取类自定义注解 ClassPool pool = ClassPool.getDefault(); // 类、注解 CtClass ctClass = pool.get(ApiTest.class.getName...()); // 通过集合获取自定义注解 Object[] clazzAnnotations = ctClass.getAnnotations(); RpcGatewayClazz rpcGatewayClazz...,这样按照名称可以只获取最需要的注解名称。...addGetstatic,获取指定类的静态域, 并将其压入栈顶 addInvokevirtual,调用实例方法 addReturn,从当前方法返回double 最终讲字节码添加到方法中,也就是会变成方法体...5.5 添加方法信息并输出 // 添加方法 ctClass.addMethod(mainMethod); // 输出类信息到文件夹下 ctClass.writeFile(); 这部分内容就比较简单了
相关的案例程序代码可以关注公众号:冰河技术 获取,也可以直接到Github和Gitee获取。...("io.binghe.bytecode.javassist.bean.User"); User类的创建方法和我们之前创建HelloWorld的类是相同的,首先是获取一个ClassPool对象,通过调用...这里,我们使用的CtField的构造方法的第一个参数是成员变量的类型,第二个参数是变量的名称,第三个字段表示将这个变量添加到哪个类。.../set方法就比较简单了,直接使用CtClass的addMethod()添加,使用CtNewMethod的setter()方法生成set方法,其中,第一个参数为生成的方法的名称setName,第二个参数表示是为哪个字段生成...Javassist中的CtMethod类,创建CtMethod类的对象时,第一个参数为方法的返回类型,第二个参数为方法的名称printName,第三个参数为方法的参数类型数组,第四个参数表示将生成的方法添加到哪个类
Class loader 类加载 如果必须修改的类是预先知道的,最简单的修改类的方式可能是以下这些: 1.通过调用ClassPool.get()获取一个CtClass对象。...CtClass的toClass方法 CtClass提供了一个便捷的方法toClass,请求当前线程的类加载器去加载CtClass表示的类。...既然这两个类是不同的,所以一个类的实例就不能分配给另一个类类型的变量了。...类,将其父类设置为Point类,然后程序加载了修改后的Rectangle类,并且创建了一个实例。...此方法可用于获取(用于缓存)一些将在Translator的onLoad()中访问的CtClass对象。
CtMethod(CtClass.voidType, "printName", new CtClass[]{}, ctClass); method.setBody("{System.out.println...($0.name);}"); ctClass.addMethod(method); method.insertBefore("System.out.println(\"miao~\");"); 生成类文件...// 生成类文件:可指定路径,默认为当前项目根目录 ctClass.writeFile("target/classes"); 创建类实例 // 创建类实例 Object person = ctClass.toClass..."); } } 找到要修改的类和方法 //找到对应的类 CtClass studentClass = pool.get("com.tenmao.learn.Student"); //找到对应的方法...需要调用修改的类CtClass.toClass,把修改的信息写入到类字节码 attempted duplicate class definition for name: "XXX" 因为对应的类信息已经加载
ClassPool:一个基于HashMap实现的CtClass对象容器,其中键是类名称,值是表示该类的CtClass对象。...Javassit官方文档中给出的代码示例如下 首先获取 ClassPool 的实例,ClassPool 主要用来修改字节码,并且在 ClassPool 中存储着 CtClass 对象,它能够按需创建出...CtClass 对象并提供给后续处理流程使用,当需要进行类修改操作的时候,可以通过 ClassPool 实例的.get()方法,获取CtClass对象。...Method 对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。 args:包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。...基本类型的参数被包装在适当基本包装器类(如 java.lang.Integer 或 java.lang.Boolean)的实例中。
相关源码可以通过关注 公众号:bugstack虫洞栈 获取 二、开发环境 JDK 1.8.0 javassist 3.12.1.GA javassist...classname:创建类路径和名称 CtClass ctClass = pool.makeClass("org.itstack.demo.javassist.HelloWorld");...// 输出类内容 ctClass.writeFile(); // 测试调用 Class clazz = ctClass.toClass(...使用 CtClass,创建我们的类信息,也就是类的路径和名称。 接下来就是给类添加方法。包括;方法的属性、类型、名称、入参、出参和方法体的内容。...在方法创建好后还需要创建一个空的构造函数,每一个类都会在编译后生成这样一个构造函数。 当方法创建完成后,我们使用 ctClass.writeFile() 进行输出方法的内容信息。
大致了解到创建在使用字节码编程的时候基本离不开三个核心类;ClassPool、CtClass、CtMethod,它们分别管理着对象容器、类和方法。...这就像我们正常写代码一样,需要设定属性的;名称、类型以及是 public 的还是 private 的以及 static 和 final 等。...如果是基本类型入参都可以使用 CtClass.doubleType,对象类型入参使用 pool.get(类.class.getName) 获取。...反射调用字节码类方法 「在测试之前,我们需要写一点反射代码来调用类的方法」 // 测试调用 Class clazz = ctClass.toClass(); Object obj = clazz.newInstance...在 Javassist 是不会进行类型的自动装箱和拆箱的,需要我们进行手动处理,否则生成类在执行会报类型错误。 当需要使用入参的时候,可以使用 $1 来获取。这也是后续做一些监控获取入参的方法。
每个class文件包含一个java类或者接口。 javassist.CtClass代表一个class文件的抽象类表示形式。...为了修改一个类的定义,用户必须首先从ClassPool对象的.get(className)方法获取一个CtClass引用。...从ClassPool中获取到的CtClass对象是可以被修改的。...ClassPool.getDefault(); CtClass cc = null; try { // 通过ClassPool获取CtClass...当一个CtClass对象被修剪后,方法的字节码则不能被访问除了方法名称、方法签名和注解。修剪过的CtClass对象不会被解冻。默认修剪值是false。
大致了解到创建在使用字节码编程的时候基本离不开三个核心类;ClassPool、CtClass、CtMethod,它们分别管理着对象容器、类和方法。...这就像我们正常写代码一样,需要设定属性的;名称、类型以及是 public 的还是 private 的以及 static 和 final 等。...如果是基本类型入参都可以使用 CtClass.doubleType,对象类型入参使用 pool.get(类.class.getName) 获取。...反射调用字节码类方法 在测试之前,我们需要写一点反射代码来调用类的方法 // 测试调用 Class clazz = ctClass.toClass(); Object obj = clazz.newInstance...在 Javassist 是不会进行类型的自动装箱和拆箱的,需要我们进行手动处理,否则生成类在执行会报类型错误。 当需要使用入参的时候,可以使用 $1 来获取。这也是后续做一些监控获取入参的方法。
; } } tips: (1)由上面的代码也可以看出使用javassist操作字节码的方式:首先获取一个类池“ClassPool”,通过类池,我们创建编译过程中的新类“CtClass”,...cc.toBytecode(); System.out.println(Arrays.toString(bytes)); System.out.println(cc.getName());//获取全部名称...System.out.println(cc.getPackageName());//获取包名 System.out.println(cc.getSimpleName());//仅获取名称...System.out.println(cc.getSuperclass());//获取父类 System.out.println(cc.getInterfaces());//获取接口...System.out.println(c.getLongName()); } } } tips: (1)关于test01,主要测试一些基本的API用法,获取名称等等
@Service注解 标注的类吗?...我们不知道统计哪个类,也不知道统计哪个方法 ,一切都是基于用户自主的配置 ---- 模型设计 核心: 使用JavaAgent获取到用户配置的数据, 匹配(排除)后 使用javassist来修改字节码,进行插桩...开始时间、用时、异常消息、异常类型、服务类名、方法名 ,当然了都是可以扩展的比如我们可以增加主机IP、应用名称、标识追踪ID等等 简单起见,我们先不引入过多的字段。...// copy 一个方法 // 修改源方法名称 $agent // 原方法中 插入模板代码 CtMethod newMethod = CtNewMethod.copy...当然了仅仅有这个javassit是无法直接运行的,我们还要依靠javaagent来实现对类的拦截
Javassist中最为重要的是ClassPool, CtClass, CtMethod以及CtField这几个类 ClassPool: 一个基于Hashtable实现的CtClass对象容器, 其中键是类名称...CtClass: CtClass表示类, 一个CtClass(编译时类)对象可以处理一个class文件, 这些CtClass对象可以从ClassPool获得. CtMethods: 表示类中的方法....它按需读取类文件来构造 CtClass 对象,并且保存 CtClass 对象以便以后使用 下面给一个简单实例方便分析 import javassist.CannotCompileException; import...ClassPool对象, 使用系统默认类路径 CtClass clazz = pool.get(Test.class.getName()); // 通过类名获取该类的 CtClass...,这样就可以把这个序列化后的字符串给其他类的变量赋值了,如果那个类有将这个变量中的字节码给实例化成对象,那么就会触发其中的static的方法。
领取专属 10元无门槛券
手把手带您无忧上云