`

采用ASM动态生成set和get方法

    博客分类:
  • JAVA
阅读更多
ASM 功能强大,采用指令操纵class文件,可以生成你所需的class文件。

package asm.model;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;

import org.apache.commons.lang.StringUtils;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;


public class DynaModelClassLoader extends ClassLoader implements Opcodes {

public Class getIntModelClass(String className, String[] fields)
throws IllegalArgumentException, SecurityException,
IllegalAccessException, InvocationTargetException, IOException {
ClassWriter cw = new ClassWriter(0);
Class exampleClass;
cw.visit(V1_1, ACC_PUBLIC, className, null, "java/lang/Object", null);
// creates a MethodWriter for the (implicit) constructor
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null,
null);
// pushes the 'this' variable
mv.visitVarInsn(ALOAD, 0);
// invokes the super class constructor
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
mv.visitInsn(RETURN);
// this code uses a maximum of one stack element and one local
// variable
mv.visitMaxs(1, 1);
mv.visitEnd();
// fields = new String[]{"dept1S", "dept2S", "dept3S", "dept4S",
// "dept5S"};
for (int i = 0; i < fields.length; i++) {
String field = fields[i];
String setMd = "set" + StringUtils.capitalize(field);
String getMd = "get" + StringUtils.capitalize(field);
cw.visitField(ACC_PRIVATE, field, "I", null, new Integer(0))
.visitEnd();// int dept1S=0;

mv = cw.visitMethod(ACC_PUBLIC, getMd, "()I", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, className, field, "I");
mv.visitInsn(IRETURN);
mv.visitMaxs(1, 1);
// mw.visitInsn(RETURN);
// this code uses a maximum of two stack elements and two local
// variables
mv.visitEnd();
cw.visitEnd();

mv = cw.visitMethod(ACC_PUBLIC, setMd, "(I)V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ILOAD, 1);
mv.visitFieldInsn(PUTFIELD, className, field, "I");
mv.visitInsn(RETURN);
mv.visitMaxs(2, 2);
// mw.visitInsn(RETURN);
// this code uses a maximum of two stack elements and two local
// variables
mv.visitEnd();
}
String[] strs = new String[]{"code"};
for (int i = 0; i < strs.length; i++) {
String setMd = "set" + StringUtils.capitalize(strs[i]);
String getMd = "get" + StringUtils.capitalize(strs[i]);
cw.visitField(ACC_PRIVATE, strs[i], "Ljava/lang/String;", null,
null).visitEnd();// int dept1S=0;

mv = cw.visitMethod(ACC_PUBLIC, getMd, "()Ljava/lang/String;", null,
null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv
.visitFieldInsn(GETFIELD, className, strs[i],
"Ljava/lang/String;");
mv.visitInsn(ARETURN);
mv.visitMaxs(1, 1);
mv.visitEnd();
cw.visitEnd();

mv = cw.visitMethod(ACC_PUBLIC, setMd, "(Ljava/lang/String;)V",
null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 1);
mv
.visitFieldInsn(PUTFIELD, className, strs[i],
"Ljava/lang/String;");
mv.visitMaxs(2, 2);
mv.visitInsn(RETURN);
mv.visitEnd();
}

cw.visitEnd();
byte[] code = cw.toByteArray();
// // 把编译好的.class文件放到他对应的包里面
// 写.class"WebRoot/WEB-INF/classes/" +
FileOutputStream fos = new FileOutputStream("bin/"+className + ".class");
fos.write(code);
fos.close();
String classFile = className.replaceAll("/", ".");
System.out.println(classFile);

DynaModelClassLoader loader = new DynaModelClassLoader();
exampleClass = loader.defineClass(classFile, code, 0, code.length);
// exampleClass.getMethods()[0].invoke(null, new Object[] { null });
return exampleClass;
}



// /* (non-Javadoc)
// * @see java.lang.ClassLoader#findClass(java.lang.String)
// */
// protected Class findClass(String name) throws ClassNotFoundException {
// // TODO Auto-generated method stub
// return super.findClass(name);
// }
  
public void testClass(String name, String[] fields) throws InstantiationException, NoSuchMethodException, IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException, IOException{
Class cls = null;
String clsName=name.replaceAll("/",".");
Class cls2=getIntModelClass(name,fields);
Object wlo2 = cls2.newInstance();
cls = findLoadedClass(clsName);

if(null==cls){
try {
cls=getIntModelClass(name,fields);
Object wlo = cls.newInstance();
// asm.WorkLoadObject wo=new asm.WorkLoadObject();
cls = wlo.getClass();
// cls.getMethods()[0].invoke(null, new Object[]{null});
java.lang.reflect.Method setMethod = cls.getMethod("setDept1S",
new Class[]{int.class});
setMethod.invoke(wlo, new Object[]{new Integer(10)});
java.lang.reflect.Method getMethod = cls.getMethod("getDept1S",
new Class[]{});
System.out.println(getMethod.invoke(wlo, new Object[]{}));
setMethod = cls.getMethod("setCode", new Class[]{String.class});
setMethod.invoke(wlo, new Object[]{new String("z11")});
getMethod = cls.getMethod("getCode", new Class[]{});
System.out.println(getMethod.invoke(wlo, new Object[]{}));
System.out.println(Type.INT_TYPE.getDescriptor());
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
System.out.println(name+" has been found.");
}

}


public static void main(final String args[]) throws Exception {
DynaModelClassLoader hd = new DynaModelClassLoader();
String className = "asm/setget/WorkLoadObject";
hd.testClass(className,new String []{"dept1S"});
}
分享到:
评论

相关推荐

    Java 反射-动态代理

    CGLIB是基于ASM库,通过字节码技术动态生成子类来实现代理。Spring框架默认使用CGLIB作为AOP(面向切面编程)的底层实现。 动态代理的应用场景广泛,包括: - AOP:在不修改源代码的情况下,为方法添加预处理和后...

    java反射性能测试分析.doc

    - **预编译的字节码**:通过动态代理或者字节码技术(如CGLIB、ASM)生成预编译的类,这些类可以直接调用,而不是通过反射,从而提高性能。 - **减少反射使用**:尽可能避免在性能敏感的代码路径上使用反射,将反射...

    Java反射机制的详细讲解及实例,有助于java深度开发

    4. 字节码操作:ASM、Javassist等库用于动态生成和修改字节码,反射是其基础。 5. 测试工具:JUnit等测试框架利用反射调用私有方法或构造函数进行测试。 6. 反序列化:将序列化的对象数据反序列化为Java对象。 三、...

    ansys命令流

    其核心在于命令流(Command Stream),也称为文本输入方式,用户通过编写脚本文件(.inp或.asm)来控制和执行分析过程。这种工作方式具有高度灵活性和自动化潜力,尤其适用于复杂工程问题的建模和求解。 在12版本中...

    -C++参考大全(第四版) (2010 年度畅销榜

    第13章 数组、指针、引用和动态分配运算符 13.1 对象数组 13.2 指向对象的指针 13.3 C++指针的类型检查 13.4 this指针 13.5 指向派生类型的指针 13.6 指向类成员的指针 13.7 引用 13.8 格式问题 13.9 C++的动态分配...

    python常用标准库及三方库借鉴.pdf

    Python标准库和第三方库详解 Python语言提供了许多有用的标准库和第三方库,帮助开发者快速、高效地开发应用程序。本文将对Python标准库和第三方库进行详细的介绍。 标准库 Python标准库是 Python语言的一部分,...

    Hibernate 的学习笔记

    - 使用 `Session` 对象提供的方法,如 `get()`、`load()`、`createQuery()` 等。 - 通过 `Query` 接口执行 HQL 查询语句。 - 利用 Criteria API 进行更为复杂的查询。 #### 七、Query 接口 - **功能**: - 执行...

    2021-2022计算机二级等级考试试题及答案No.10916.docx

    - **解析**: HTTP请求方法包括GET、POST、PUT等,SET不是一个有效的HTTP请求方法。 #### 18. Internet 域名中的“com”代表的含义 - **知识点**: “com”是Internet域名中的顶级域名之一。 - **解析**: “com”代表...

    Linux内核系统 panic log 记录

    1. **日志信息获取**:系统崩溃时,内核会生成一系列与崩溃相关的日志信息,这些信息对于理解崩溃的原因至关重要。 2. **文件系统交互**:为了确保这些日志信息能够在系统重启后被保留,需要将它们写入到文件系统中...

    sql面试题\oracle面试题目

    - 使用`DBMS_METADATA.GET_DDL('TABLE', 'table_name')`获取更详细的DDL信息。 #### 6. 查看数据库引擎的报错 - 使用`SELECT * FROM v$diag_info`查看诊断信息的位置。 - 使用`SELECT * FROM v$database`和`v$...

    uboott移植实验手册及技术文档

    了解 U-Boot-1.3.1 的代码结构,掌握其移植方法。 【实验环境】 1、Ubuntu 7.0.4发行版 2、u-boot-1.3.1 3、FS2410平台 4、交叉编译器 arm-softfloat-linux-gnu-gcc-3.4.5 【实验步骤】 一、建立自己的平台...

Global site tag (gtag.js) - Google Analytics