使用ASM动态生成一个接口的实现类,接口如下:
public interface ISayHello { public void MethodA(); public void MethodB(); public void Abs(); }
具体实现如下:
public class InterfaceHandler extends ClassLoader implements Opcodes { public static Object MakeClass(Class<?> clazz) throws Exception { String name = clazz.getSimpleName(); String className = name + "$imp"; String Iter = clazz.getName().replaceAll("\\.", "/"); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS); cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, className, null, "java/lang/Object", new String[] { Iter }); // 空构造 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); mv.visitEnd(); // 实现接口中所有方法 Method[] methods = clazz.getMethods(); for (Method method : methods) { MakeMethod(cw, method.getName(), className); } cw.visitEnd(); //写入文件 byte[] code = cw.toByteArray(); FileOutputStream fos = new FileOutputStream("d:/com/" + className + ".class"); fos.write(code); fos.close(); //从文件加载类 InterfaceHandler loader = new InterfaceHandler(); Class<?> exampleClass = loader.defineClass(className, code, 0, code.length); Object obj = exampleClass.getConstructor().newInstance(); return obj; } private static void MakeMethod(ClassWriter cw, String MethodName, String className) { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, MethodName, "()V", null, null); //mv.visitCode(); //Label l0 = new Label(); //mv.visitLabel(l0); //mv.visitLineNumber(8, l0); mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitLdcInsn("调用方法 [" + MethodName + "]"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); //Label l1 = new Label(); //mv.visitLabel(l1); //mv.visitLineNumber(9, l1); mv.visitInsn(RETURN); //Label l2 = new Label(); //mv.visitLabel(l2); //mv.visitLocalVariable("this", "L" + className + ";", null, l0, l2, 0); mv.visitMaxs(2, 1); mv.visitEnd(); } public static void main(final String args[]) throws Exception { ISayHello iSayHello = (ISayHello) MakeClass(ISayHello.class); iSayHello.MethodA(); iSayHello.MethodB(); iSayHello.Abs(); } }
注意,使用ASM访问属性和方法的时候,会返回一个Visitor对象,如属性为FieldVisitor,方法为MethodVisitor。
使用反编译工具查看生成的字节码文件内容如下:
public class ISayHello$imp implements ISayHello { public void MethodA() { System.out.println("调用方法 [MethodA]"); } public void MethodB() { System.out.println("调用方法 [MethodB]"); } public void Abs() { System.out.println("调用方法 [Abs]"); } }
相关推荐
在模拟Spring的AOP实现原理时,我们可以用ASM创建一个代理类,这个代理类会在目标方法调用前后插入自定义的行为,例如记录日志、执行事务控制等。以下是一个简化的步骤: 1. 创建`ClassWriter`实例,并设定类的访问...
总的来说,`asm-proxy` 是一个利用 ASM 实现的便捷工具,它简化了动态生成接口实现的过程,使得开发者可以专注于编写方法逻辑,而不必关心生成类的细节。如果你需要处理动态代码生成或接口代理的问题,学习并应用 `...
Java 中动态创建接口的实现方法是指通过 Java 语言提供的机制,动态地生成接口的实现类,以满足各种应用场景的需求。这种方法可以应用于多种领域,例如 ORM 框架、分布式服务框架、AOP 等等。 在 Java 中,动态...
8代表Java 8),访问标志(`ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE`表示公共、抽象和接口),接口的全名,签名(对于接口,通常是null),超类名称(对于接口也是`"java/lang/Object"`),以及接口实现列表...
4. **构建和加载类**: 最后,使用ASM的ClassWriter生成新的字节码,然后通过DexClassLoader或其他类加载器动态加载到Android系统中。 MonitorDemo-master项目很可能包含了一个示例的Android无痕埋点框架实现,包括...
3. **元编程**:ASM库允许开发者在运行时动态创建或修改类,这对于构建元编程框架或字节码级别的调试工具至关重要。 4. **字节码分析**:ASM-Tree提供了对字节码的高级抽象,便于进行代码分析和修改,对于字节码级别...
ASM提供了底层的字节码操作能力,而CGlib则在其上构建了一个更易于使用的API,使得开发者无需直接与ASM的复杂接口打交道,就能实现类的动态扩展和代理。CGlib封装了ASM的一些细节,提供了更高级别的抽象,使得开发者...
接着是`asmAopGenerator.java`,这个文件可能包含了ASM库的使用,用于动态生成代理类。ASM通过`ClassWriter`和`MethodVisitor`等接口,可以生成或修改字节码。`asmAopGenerator`可能负责生成一个代理类,这个代理类...
在Java中,由于无法直接对非接口实现类进行代理(JDK动态代理仅支持接口代理),所以cglib通过继承目标类的方式来创建代理对象。当一个类没有接口或者为了性能考虑不希望使用接口时,cglib就显得尤为重要。 cglib的...
1. 动态生成类:ASM允许你在运行时动态创建新的类和接口。这对于实现代码生成器或者运行时类型定制非常有用。例如,你可以创建一个表示数据库记录的动态类,其中包含字段和方法,这些都根据数据库表结构自动生成。 ...
ASM库允许开发者直接操作字节码,创建和修改类,甚至在运行时动态生成类。ASM通过访问者模式设计,使得在字节码级别进行操作变得简洁高效。ASM支持JVM规范的所有版本,包括Java 8及更高版本的特性,如lambda表达式和...
1. **动态代理**: 创建动态代理类,用于模拟接口的实现,比如在不修改源代码的情况下增强或拦截方法调用。 2. **代码分析**: 分析已存在的类和方法,用于性能优化、代码理解和调试。 3. **代码生成**: 动态生成新的...
使用JDK动态代理,我们需要实现InvocationHandler接口,然后通过Proxy类的newProxyInstance方法创建代理对象。这个方法需要传入目标接口的类加载器、接口数组以及我们实现的InvocationHandler实例。 **CGLIB**: ...
3. **插件系统**:利用ASM动态生成插件类,实现灵活的插件化架构。 4. **动态语言实现**:一些动态语言的Java实现,如Groovy和Jython,使用ASM来生成Java字节码。 5. **框架开发**:例如Spring AOP和Hibernate ORM等...
cglib包及依赖汉cglib3.1和asm4.2,主要作用是...JDK的动态代理用起来非常简单,但它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的继承的类,该怎么办?现在我们可以使用CGLIB包
1. **字节码生成**:ASM允许开发者在运行时动态创建新的类和接口,或者修改已有的类。 2. **代码分析**:ASM可以解析类的字节码,帮助理解类的结构和行为,这对于调试、测试和性能分析非常有用。 3. **字节码优化**...
4. **示例**:有时,压缩包中还会包含示例代码,演示如何使用ASM来实现某些特定功能,如创建动态代理、修改类或方法的行为等。 5. **构建脚本和配置文件**:如`pom.xml`(如果是Maven项目)或者`build.gradle`...
- **动态代理**:通过ASM,开发者可以创建动态代理类,实现运行时接口的动态实现。 - **代码分析**:在性能调优、代码安全审计或白盒测试中,ASM能帮助解析类结构和方法体。 - **代码优化**:ASM可以用来对字节码...
- 动态代理:创建接口的代理类,使得可以在运行时动态实现这些接口并调用其方法。 - 类分析:解析类文件,获取类的结构信息,如字段、方法、注解等。 - 字节码生成:允许在运行时创建新的类或者修改现有类的字节码,...