- 浏览: 732879 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
luger:
谢谢 解决了我的问题
spring import jar中的bean配置文件 -
diamondy:
<div class="quote_title ...
利用ASM和Javassist动态生成Class 类(set和get) -
sunny80062951414:
没有fieldinfo信息啊。
利用ASM和Javassist动态生成Class 类(set和get) -
somefuture:
求解!求思路!完全迷茫中。
珍藏经典面试题目一个 -
xiao1227372602:
lionbule 写道xiao1227372602 写道请问下 ...
Linux 命令 alternatives和update-alternatives
利用jvm的指令集直接构造class,简单的bean class 还是有应用场景的。在此利用ASM和Javassist各造例子以备忘!
抽象类:SimpleJbean
public abstract class SimpleJbean { public abstract byte[] createBeanClass(String className, List<FieldInfo> fields); }
ASM实现:
import java.util.List; 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; import com.FieldInfo; import com.SimpleJbean; /** * SimpleJbean.java. 2011-12-28下午4:12:18 @author LionBule. */ public class SimpleJbeanAsm extends SimpleJbean implements Opcodes { @Override public byte[] createBeanClass(String className, List<FieldInfo> fields) { ClassWriter cw = new ClassWriter(0); 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); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); // create set&get methods for (FieldInfo f : fields) { addMethod(cw, mv, className, f); } return cw.toByteArray(); } private void addMethod(ClassWriter cw, MethodVisitor mv, String className, FieldInfo fieldInfo) { String fieldName = fieldInfo.name; String setMethodName = "set" + StringUtils.capitalize(fieldName); String getMethodName = "get" + StringUtils.capitalize(fieldName); String typeof = Type.getType(fieldInfo.type).getDescriptor(); String getof = getof(typeof); String setof = setof(typeof); int[] loadAndReturnOf = loadAndReturnOf(typeof); //add field cw.visitField(ACC_PRIVATE, fieldName, typeof, null, 0).visitEnd(); // getMethod mv = cw.visitMethod(ACC_PUBLIC, getMethodName, getof, null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, className, fieldName, typeof); mv.visitInsn(loadAndReturnOf[1]); mv.visitMaxs(2, 1); mv.visitEnd(); // setMethod mv = cw.visitMethod(ACC_PUBLIC, setMethodName, setof, null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(loadAndReturnOf[0], 1); mv.visitFieldInsn(PUTFIELD, className, fieldName, typeof); mv.visitInsn(RETURN); mv.visitMaxs(3, 3); mv.visitEnd(); } private String setof(String typeof) { return "(" + typeof + ")V"; } private String getof(String typeof) { return "()" + typeof; } private int[] loadAndReturnOf(String typeof) { if (typeof.equals("I") || typeof.equals("Z")) { return new int[]{ILOAD,IRETURN}; } else if (typeof.equals("J")) { return new int[]{LLOAD,LRETURN}; } else if (typeof.equals("D")) { return new int[]{DLOAD,DRETURN}; } else if (typeof.equals("F")) { return new int[]{FLOAD,FRETURN}; } else { return new int[]{ALOAD,ARETURN}; } } }
Javassist实现:
import java.util.List; import org.apache.commons.lang.StringUtils; import com.FieldInfo; import com.SimpleJbean; import javassist.ClassPool; import javassist.CtClass; import javassist.CtField; import javassist.CtMethod; import javassist.CtNewMethod; /** * JbeanUtil.java. 2011-12-26下午4:05:02 @author LionBule. */ public class SimpleJbeanJs extends SimpleJbean { private final static String SETTER_STR = "set"; private final static String GETTER_STR = "get"; // type/fieldName private final static String fieldTemplate = "private %s %s;"; @Override public byte[] createBeanClass(String className, List<FieldInfo> fields){ try{ ClassPool cpool = ClassPool.getDefault(); CtClass cc = cpool.makeClass(StringUtils.capitalize(className)); String setMethodName = null; String getMethodName = null; for (FieldInfo fi : fields) { setMethodName = SETTER_STR + StringUtils.capitalize(fi.name); getMethodName = GETTER_STR + StringUtils.capitalize(fi.name); CtField newField = CtField.make(String.format(fieldTemplate, fi.type.getName(), fi.name), cc); cc.addField(newField); CtMethod ageSetter = CtNewMethod.setter(setMethodName, newField); cc.addMethod(ageSetter); CtMethod ageGetter = CtNewMethod.getter(getMethodName, newField); cc.addMethod(ageGetter); } return cc.toBytecode(); }catch(Exception e){ throw new RuntimeException(e); } } }
单元测试:
import static org.junit.Assert.*; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.StringUtils; import org.junit.Before; import org.junit.Test; import com.asm.util.SimpleJbeanAsm; import com.javassist.util.SimpleJbeanJs; /** * SimpleJbeanTest.java. 2011-12-30下午9:00:09 @author LionBule. */ public class SimpleJbeanTest extends ClassLoader { private String className; private List<FieldInfo> fields; @Before public void setUp() throws Exception { className = "User"; FieldInfo testString = new TestFieldInfo(String.class, "name", "lionbule"); FieldInfo testInt = new TestFieldInfo(int.class, "age", 27); FieldInfo testLong = new TestFieldInfo(long.class, "count", 9999999999L); FieldInfo testFloat = new TestFieldInfo(float.class, "score", 89.312F); FieldInfo testDouble = new TestFieldInfo(double.class, "number", 89.3121313D); FieldInfo testBoolean = new TestFieldInfo(Boolean.class, "isStudent", false); fields = new ArrayList<FieldInfo>(); fields.add(testString); fields.add(testInt); fields.add(testLong); fields.add(testFloat); fields.add(testDouble); fields.add(testBoolean); } @Test public void testSimpleJbeanJs() { try { SimpleJbean simpleJbean = new SimpleJbeanJs(); doAction(simpleJbean); } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } } @Test public void testSimpleJbeanAsm() { try { SimpleJbean simpleJbean = new SimpleJbeanAsm(); doAction(simpleJbean); } catch (Exception e) { e.printStackTrace(); fail(e.getMessage()); } } private void doAction(SimpleJbean simpleJbean) throws Exception { byte[] classBytes = simpleJbean.createBeanClass(className, fields); Class<?> userClass = this.defineClass(className, classBytes, 0, classBytes.length); //invoker Object user = userClass.newInstance(); TestFieldInfo tempField = null; for (FieldInfo t : fields) { tempField = (TestFieldInfo) t; String setMethodName = "set" + StringUtils.capitalize(tempField.name); String getMethodName = "get" + StringUtils.capitalize(tempField.name); Method setMethod = userClass.getMethod(setMethodName, new Class[] { tempField.type }); setMethod.invoke(user, new Object[] { tempField.value }); Method getMethod = userClass.getMethod(getMethodName, new Class[] {}); System.out.println(getMethod.toGenericString()); Object result = getMethod.invoke(user, new Object[] {}); assertEquals(tempField.value, result); } } }
ASM和Javassist的区别和侧重点,google下有很多资料,不再详述。
看了上面列子也会有大概的感触!
源码地址:
http://lionbule-java-open.googlecode.com/svn/trunk/lionbule-compile
reference:
1. http://asm.ow2.org/doc/developer-guide.html
2. http://download.forge.objectweb.org/asm/asm4-guide.pdf
评论
9 楼
diamondy
2015-07-14
sunny80062951414 写道
没有fieldinfo信息啊。
public class FieldInfo {
public String name;
public Class<?> type;
public FieldInfo(Class<?> type, String name) {
this.type = type;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Class<?> getType() {
return type;
}
public void setType(Class<?> type) {
this.type = type;
}
}
public class TestFieldInfo extends FieldInfo {
public Object value;
public TestFieldInfo(Class<?> type, String name, Object value) {
super(type, name);
this.value = value;
}
}
8 楼
sunny80062951414
2015-01-07
没有fieldinfo信息啊。
7 楼
bjzhangliang
2013-11-20
TestFieldInfo类:
public class TestFieldInfo extends FieldInfo{
public Object value;
public TestFieldInfo(Class<?> type, String name, Object value) {
super(type, name);
this.value = value;
}
}
如果有不对的地方,请指正.
public class TestFieldInfo extends FieldInfo{
public Object value;
public TestFieldInfo(Class<?> type, String name, Object value) {
super(type, name);
this.value = value;
}
}
如果有不对的地方,请指正.
6 楼
bjzhangliang
2013-11-19
SimpleJbean 是抽象 的
5 楼
bjzhangliang
2013-11-19
TestFieldInfo:这个类怎么写?
4 楼
lionbule
2012-02-20
Mr_caochong 写道
Mr_caochong 写道
非常好的例子,对我帮助很大,可是请问,如果生成package信息呢
这个问题已经解决了。
建议阅读ASM相关的官方资料,有很完整的讲解! javassist是比较傻瓜化的实现,具体选型由自己的需求决定。
3 楼
Mr_caochong
2012-02-08
Mr_caochong 写道
非常好的例子,对我帮助很大,可是请问,如果生成package信息呢
这个问题已经解决了。
2 楼
Mr_caochong
2012-02-08
请问extends 怎么写
1 楼
Mr_caochong
2012-02-07
非常好的例子,对我帮助很大,可是请问,如果生成package信息呢
发表评论
-
spring import jar中的bean配置文件
2012-06-12 17:28 11480在spring中import resource file,有两 ... -
Adding OSGi metadata to existing projects without changing the packaging type
2012-06-05 10:20 1876http://felix.apache.org/site/ap ... -
比较If else 和 try catch 的jvm指令
2012-06-01 10:40 2691编码时过度关注某个点性能,有时候整体性能适得其反!关于if e ... -
java 类加载实例分析之tomcat6.x
2012-03-26 18:47 0[前言] 研究OSGI已经有一段时间,而OSGI的灵魂就在于 ... -
Java 数字转字符串 自动补0
2012-02-20 14:18 2995java中数字转字符,在确定位数的情况下,左边自动补0以对齐 ... -
Java HotSpot VM Options
2012-01-05 11:03 1863http://www.oracle.com/techne ... -
jvm 指令集
2011-12-30 19:46 2213JVM指令助记符 变量到操作数栈:iload,iload_ ... -
switch 和 if elseif 哪个效率高?
2011-12-30 11:23 3265switch 和 if elseif 哪个效率高? ... -
列表和数组的区别
2011-12-27 10:59 4265在数据结构中有多种集合的表现形式!而集合其实就是一个真实 ... -
JVM 选择合适的GC算法
2011-12-19 15:17 1869Selecting a Collector Unles ... -
动态修改JVM 部分参数
2011-12-05 17:00 6922参考地址: http://rednaxelafx.iteye. ... -
Java 快捷读取CLASSPATH下的资源文件
2011-11-30 11:26 17363在JVM中查找classpath下的资源文件,使用Class. ... -
java main函数为非守护线程(实时线程)
2011-11-23 14:29 4375一直认为main为守护线程,google线程相关的资料时,发现 ... -
Solution to Eclipse Warning with SVN
2011-11-14 16:58 1429Solution to Eclipse Warning wit ... -
Java简单数据类型
2011-09-29 11:27 1384简单类型 大小 ... -
spring3.0 单元测试
2011-09-27 18:42 2139spring3.0.0之后的版本,官方极力推荐使用如下方式做单 ... -
logback 之 创建 RollingFileAppender
2011-09-24 17:01 8112最近有需求要将context信息写入文件,以备后续数据分析。本 ... -
logback 之encoder和layout
2011-09-24 16:49 6952encoder 和 layout 在作用上没有本质区别。但是自 ... -
JAVA 排序算法
2011-08-30 21:57 2152import java.util.Random; ... -
hashmap的正确使用方法
2011-08-29 12:04 1445近期发生太多关于集合类使用不当导致的bug, 在此记录下关于h ...
相关推荐
ASM操作字节码,动态生成Java类class文件,模拟Spring的AOP实现原理。
NULL 博文链接:https://name327.iteye.com/blog/1554558
NULL 博文链接:https://bijian1013.iteye.com/blog/2382393
Javassist 提供了java类库,...与其他同类工具(asm等)不同的是,Javassist提供了两个层面的API: 1.java代码层 2.字节码层 通过java代码层,开发者即时对字节码不是很熟悉,也可以非常方便快速的完成字节码的修改。
通过使用运行时代码生成技术,您可以在不定义Class的情况下创建一个实现某些特定接口或扩展类的实例。 通过直接启动ProxyCreator实例,您可以获得利用 ASM、Javassist、ByteBuddy、CGLIB 和传统 JDK 动态代理的特定...
它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元...
JavaAgent Javassist 与 Asm JavaAgent 字节码动态编程项目
Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶...直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。
它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元...
它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元...
它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元...
它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元...
ASM是一个java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class文件...
avassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 ...直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。
ASM是一个java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class...
总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是...
ASM是一套java字节码生成架构,它可以动态生成二进制格式的stub类或其它代理类, 或者在类被java虚拟机装入内存之前,动态修改类。 现在挺多流行的框架都使用到了asm.所以从aop追溯来到了这。
Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶...直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。
可以将keil、wave生成的hex文件反汇编成汇编语言
08 - ASM使用ClassWrite生成接口 - 简书1