`

采用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"});
}
分享到:
评论

相关推荐

    ASM操作字节码,动态生成Java类class文件

    ASM操作字节码,动态生成Java类class文件,模拟Spring的AOP实现原理。

    asm动态生成class,并且动态加载执行

    NULL 博文链接:https://name327.iteye.com/blog/1554558

    asm动态代理jar包

    asm动态代理jar包,是java开发的好的工具类

    cglib 和asm jar包

    总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是...

    08 - ASM使用ClassWrite生成接口 - 简书1

    08 - ASM使用ClassWrite生成接口 - 简书1

    HEX2ASM单片机 hex文件生成asm文件

    可以将keil、wave生成的hex文件反汇编成汇编语言

    oracle不使用oracleasm的包配置ASM磁盘配置方法

    oracle不使用oracleasm的包配置ASM磁盘配置方法

    基于JPA及ASM9实现自动接口开发

    实现基于ASM9,动态生成entity、repository、service、serviceImpl、controller相关.class 可根据库表,一键生成新增、修改删除、查询等接口 实现部分基于mybatis-plus,动态代码生成(相关包,未包含) 数据库文件...

    代码生成工具asm-3.2

    代码生成工具asm-3.2 下载地址:http://asm.ow2.org/

    asm 最新版手册

    它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元...

    asm4-guide.pdf

    它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元...

    ASM4使用指南

    它可以用于修改现有类或直接以二进制形式动态生成类。ASM提供了一些常见的字节码转换和分析算法,可以从中构建自定义复杂转换和代码分析工具。ASM提供与其他Java字节码框架类似的功能,但专注于 性能。因为它的设计...

    asm5.0安装包

    ASM是一套java字节码生成架构,它可以动态生成二进制格式的stub类或其它代理类, 或者在类被java虚拟机装入内存之前,动态修改类。 现在挺多流行的框架都使用到了asm.所以从aop追溯来到了这。

    asm4.1 jar+demo+doc

    与 BCEL 和 SERL 不同,ASM 提供了更为现代的编程模型。对于 ASM 来说,Java class 被描述为一棵树;使用 “Visitor” 模式遍历整个二进制结构;事件驱动的处理方式使得用户只需要关注于对其编程有意义的部分,而...

    asm.jar各个版本

    asm-1.3.3.jar, asm-1.3.4.jar, asm-1.3.5.jar, asm-1.4.1.jar, asm-1.4.2.jar, asm-1.4.3.jar, asm-1.4.jar, asm-1.5.1.jar, asm-1.5.2.jar, asm-1.5.3.jar, asm-2.0.jar, asm-2.1.jar, asm-2.2.1-sources.jar, asm...

    asm5.0 源码+demo+doc

    与 BCEL 和 SERL 不同,ASM 提供了更为现代的编程模型。对于 ASM 来说,Java class 被描述为一棵树;使用 “Visitor” 模式遍历整个二进制结构;事件驱动的处理方式使得用户只需要关注于对其编程有意义的部分,而...

    asm操作指南(中文)

    ASM是一个java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class...

    09 - ASM使用ClassWrite生成接口+字段+方法 - 简书1

    09 - ASM使用ClassWrite生成接口+字段+方法 - 简书1

    ASM 4 Guide 中文版

    它可以动态生成二进制格式的stub类或其他代理类,或者在类被JAVA虚拟机装入内存之前,动态修改类。在ASM中提供了诸多的API用于对类的内容进行字节码操作的方法。与传统的BCEL和SERL不同,在ASM中提供了更为优雅和...

    ASM4中文使用指南.zip

    它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元...

Global site tag (gtag.js) - Google Analytics