- 浏览: 741655 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
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 11540在spring中import resource file,有两 ... -
Adding OSGi metadata to existing projects without changing the packaging type
2012-06-05 10:20 1917http://felix.apache.org/site/ap ... -
比较If else 和 try catch 的jvm指令
2012-06-01 10:40 2737编码时过度关注某个点性能,有时候整体性能适得其反!关于if e ... -
java 类加载实例分析之tomcat6.x
2012-03-26 18:47 0[前言] 研究OSGI已经有一段时间,而OSGI的灵魂就在于 ... -
Java 数字转字符串 自动补0
2012-02-20 14:18 3040java中数字转字符,在确定位数的情况下,左边自动补0以对齐 ... -
Java HotSpot VM Options
2012-01-05 11:03 1918http://www.oracle.com/techne ... -
jvm 指令集
2011-12-30 19:46 2249JVM指令助记符 变量到操作数栈:iload,iload_ ... -
switch 和 if elseif 哪个效率高?
2011-12-30 11:23 3346switch 和 if elseif 哪个效率高? ... -
列表和数组的区别
2011-12-27 10:59 4314在数据结构中有多种集合的表现形式!而集合其实就是一个真实 ... -
JVM 选择合适的GC算法
2011-12-19 15:17 1927Selecting a Collector Unles ... -
动态修改JVM 部分参数
2011-12-05 17:00 6991参考地址: http://rednaxelafx.iteye. ... -
Java 快捷读取CLASSPATH下的资源文件
2011-11-30 11:26 17414在JVM中查找classpath下的资源文件,使用Class. ... -
java main函数为非守护线程(实时线程)
2011-11-23 14:29 4428一直认为main为守护线程,google线程相关的资料时,发现 ... -
Solution to Eclipse Warning with SVN
2011-11-14 16:58 1468Solution to Eclipse Warning wit ... -
Java简单数据类型
2011-09-29 11:27 1423简单类型 大小 ... -
spring3.0 单元测试
2011-09-27 18:42 2184spring3.0.0之后的版本,官方极力推荐使用如下方式做单 ... -
logback 之 创建 RollingFileAppender
2011-09-24 17:01 8195最近有需求要将context信息写入文件,以备后续数据分析。本 ... -
logback 之encoder和layout
2011-09-24 16:49 7013encoder 和 layout 在作用上没有本质区别。但是自 ... -
JAVA 排序算法
2011-08-30 21:57 2195import java.util.Random; ... -
hashmap的正确使用方法
2011-08-29 12:04 1491近期发生太多关于集合类使用不当导致的bug, 在此记录下关于h ...
相关推荐
ASM是一个开源的Java字节码操控和分析框架,它能够用来动态生成类或者增强已有类的功能。ASM可以被用来创建Java代理、实现元编程、甚至深入到Java虚拟机(JVM)层面进行性能优化。在Java开发中,ASM库允许我们直接...
NULL 博文链接:https://name327.iteye.com/blog/1554558
ASM是一个底层的Java字节码操控和分析框架,它可以用来动态生成类或者增强已有类的功能。ASM提供了一套非常底层的API,可以精确地控制类和方法的生成,但同时也需要编写更复杂的代码。ASM主要用于库开发者,而不是...
ASM是一个强大的Java字节码操控和分析框架,它可以直接生成和修改Java类的字节码。...总的来说,ASM是一个强大的工具,它允许开发者在运行时动态生成和修改Java类,从而在很多场景下提供灵活和高效的解决方案。
Javassist 提供了java类库,...与其他同类工具(asm等)不同的是,Javassist提供了两个层面的API: 1.java代码层 2.字节码层 通过java代码层,开发者即时对字节码不是很熟悉,也可以非常方便快速的完成字节码的修改。
2. **测试**:在单元测试中,可以通过CGLib生成类的模拟对象(mock object),方便对类的方法进行模拟和测试。 3. **动态数据访问**:例如ORM框架如Hibernate,使用CGLib动态创建数据访问对象(DAO)。 总的来说,...
另外,有一些库如ASM、Javassist和Byte Buddy,它们提供了更高级的字节码操作能力,可以让我们更方便地生成和修改Java类的字节码。这些库通常用于AOP(面向切面编程)、动态代理或者在运行时优化代码等场景。例如,...
在这个“JavaAgent: Javassist与Asm JavaAgent字节码动态编程项目”中,我们将深入探讨如何利用Javassist和ASM这两个库来实现JavaAgent。 首先,Javassist是一个开源的Java字节码操作框架,它使得开发者可以在运行...
ASM是一个字节码操控和分析框架,它可以用来动态生成类或者增强已有类的功能。ASM提供了一套直接操作Java字节码的底层API,允许开发者在运行时对类进行深度定制。ASM的强大之处在于其灵活性,但同时也要求使用者对...
CGLIB通过字节码技术生成代理类,它使用ASM库来操作字节码,因此可以为非接口类型创建代理。CGLIB的使用主要包括: 1. 引入CGLIB库。 2. 创建Enhancer对象,它是CGLIB的核心,用于生成代理类。 3. 设置回调机制,即...
2. 灵活性强:ASM提供了一套灵活的API,允许开发者直接操作字节码,从而实现高度自定义的类修改和生成。 3. 小巧轻便:ASM库本身体积小,适合嵌入式或资源有限的环境。 4. 面向字节码级别:ASM直接处理字节码,而...
ASM是一个强大的Java字节码操控和分析框架,它可以直接生成和修改Java类文件。ASM-3.2是这个工具的一个版本,主要用于动态程序分析和字节码操纵。这个框架广泛应用于许多领域,如代码混淆、性能监控、动态代理以及...
ASM允许开发者在运行时动态生成和修改类。通过ASM,我们可以: - 创建全新的类、接口或继承已有类的子类。 - 修改已有的类,添加、删除或修改方法、字段。 - 在方法体中插入代码,实现AOP(面向切面编程)的动态代理...
Map作为键值对的数据结构,可以很好地映射到类的属性上,通过这种方式,我们可以自动生成类的实例,从而实现灵活的代码生成和数据绑定。 在Java中,动态生成类的一种常见方法是使用Java的`java.lang.reflect.Proxy`...
`ClassWriter`是ASM提供的一种用于创建字节码表示的类,它可以自动生成字节码的框架信息,使得我们能方便地构建Java类和接口。 首先,我们需要了解ASM的几个关键概念: 1. `ClassVisitor`: 这是ASM的核心接口,它...
ASM是一个低级别的库,可以直接操作和生成类的字节码,这在创建编译器、代码分析工具以及运行时代码修改等方面非常有用。下面将详细解释ASM4及其在JAVA开发中的应用。 首先,ASM4提供了访问和修改Java类和方法的...
通过使用运行时代码生成技术,您可以在不定义Class的情况下创建一个实现某些特定接口或扩展类的实例。 通过直接启动ProxyCreator实例,您可以获得利用 ASM、Javassist、ByteBuddy、CGLIB 和传统 JDK 动态代理的特定...
avassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 ...直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。
它能被用来动态生成类或者增强既有类的功能。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。Java class 被存储在严格格式定义的 .class 文件里,这些类文件拥有足够的元...
它使用ASM库在内存中构建新的字节码,生成的目标类会继承自原始类。因此,对于没有实现接口的类,CGLIB可以提供动态代理功能。 性能方面,CGLIB通常比JDK动态代理更快,因为它是基于字节码生成的子类,而JDK动态...