使用javassist动态生成类的配置代码
说明:
Javassist(JAVA 编程 ASSISTant)使 Java 字节码操作变得简单。 它是一个用 Java 编辑字节码的类库。它使 Java 程序能够在运行时定义新类,并在 JVM 加载时修改类文件。 与其他类似的字节码编辑器不同,Javassist 提供两个级别的 API:源级别和字节码级别。 如果用户使用源级 API,他们可以在不知道 Java 字节码规范的情况下编辑类文件。 整个 API 仅使用 Java 语言的词汇表进行设计。 您甚至可以以源文本的形式指定插入的字节码;Javassist 即时编译它。 另一方面,字节码级 API 允许用户直接编辑类文件作为其他编辑器。
配置环境:
- javassist依赖:
<dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.29.1-GA</version> </dependency>
- 环境配置:
–add-opens java.base/java.lang=ALL-UNNAMED
–add-opens java.base/sun.net.util=ALL-UNNAMED
使用javassist生成类:
代码:
package com.user; import javassist.*; import java.lang.reflect.Method; public class JavassistTest { public static void main(String[] args) throws Exception{ //获取类池 ClassPool pool = ClassPool.getDefault(); //通过类路径创建类 CtClass ctClass = pool.makeClass("com.user.Test"); //为类创建方法(参数:1.方法返回值类型 2.方法名 3.方法形参列表 4.方法所属类) CtMethod ctMethod = new CtMethod(CtClass.voidType, "execute", new CtClass[]{}, ctClass); //设置方法的修饰符列表 ctMethod.setModifiers(Modifier.PUBLIC); //设置方法体 ctMethod.setBody("{System.out.println(\"hello world\");}"); //给类添加方法 ctClass.addMethod(ctMethod); //测试:使用反射机制测试方法调用 Class<?> aClass = ctClass.toClass(); Object o = aClass.newInstance(); Method method = aClass.getDeclaredMethod("execute"); method.invoke(o); } }
执行结果:
使用javassist生成类并实现接口:
接口已定义好:
package com.user; public interface Dao { public int insert(); public int delete(); public int update(); public void select(); }
代码:
package com.user; import javassist.*; import java.lang.reflect.Method; import java.util.Arrays; public class JavassistTestImpl { public static void main(String[] args) throws Exception { //获取类池 ClassPool pool = ClassPool.getDefault(); //制造类 CtClass ctClass = pool.makeClass("com.user.TestImpl"); //制造接口 CtClass ctInterface = pool.makeInterface("com.user.Dao"); //类实现接口 ctClass.addInterface(ctInterface); //获取接口中的所有方法 Method[] methods = Dao.class.getDeclaredMethods(); //类实现接口中的所有方法 Arrays.stream(methods).forEach(method->{ try { //拼接方法头+方法体 StringBuilder sb = new StringBuilder(); sb.append("public");//方法修饰符 sb.append(" "); sb.append(method.getReturnType().getName());//方法返回值类型 sb.append(" "); sb.append(method.getName());//方法名 sb.append("("); Class<?>[] parameterTypes = method.getParameterTypes(); for (int i = 0; i < parameterTypes.length; i++) { sb.append(parameterTypes[i].getName());//参数类型 sb.append(" "); sb.append("arg"+i);//参数名,随意指定,但不能重名 if(i != parameterTypes.length-1) { sb.append(","); } } sb.append(")"); sb.append("{"); String simpleName = method.getReturnType().getSimpleName();//根据返回值类型写return语句 if("String".equals(simpleName)){ sb.append("return \"hello\";"); }else if("int".equals(simpleName)){ sb.append("return 1;"); }else if("void".equals(simpleName)){ sb.append("System.out.println(\"hello\");"); } sb.append("}"); //创建方法(参数:方法头+方法体,所属类) CtMethod ctMethod = CtNewMethod.make(sb.toString(),ctClass); ctClass.addMethod(ctMethod); } catch (CannotCompileException e) { e.printStackTrace(); } }); //测试 Class<?> aClass = ctClass.toClass(); Dao o = (Dao)aClass.newInstance(); o.select(); System.out.println(o.insert()); } }
执行结果:
到此这篇关于使用javassist动态生成类的文章就介绍到这了,更多相关javassist动态生成类内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Java多线程编程中synchronized关键字的基础用法讲解
Java的synchronized关键字用于修饰线程同步,用以线程资源共享的目的等,下面就带来简单的Java多线程编程中synchronized关键字的基础用法讲解2016-06-06SpringBoot使用Sa-Token实现账号封禁、分类封禁、阶梯封禁的示例代码
本文主要介绍了SpringBoot使用Sa-Token实现账号封禁、分类封禁、阶梯封禁的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2023-07-07
最新评论