`

使用ASM动态创建接口实现类

阅读更多

使用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]");
  }
}

 

 

 

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

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

    在模拟Spring的AOP实现原理时,我们可以用ASM创建一个代理类,这个代理类会在目标方法调用前后插入自定义的行为,例如记录日志、执行事务控制等。以下是一个简化的步骤: 1. 创建`ClassWriter`实例,并设定类的访问...

    asm-proxy:使用asm生成接口的impl,其中方法实现作为函数提供

    总的来说,`asm-proxy` 是一个利用 ASM 实现的便捷工具,它简化了动态生成接口实现的过程,使得开发者可以专注于编写方法逻辑,而不必关心生成类的细节。如果你需要处理动态代码生成或接口代理的问题,学习并应用 `...

    Java中如何动态创建接口的实现方法

    Java 中动态创建接口的实现方法是指通过 Java 语言提供的机制,动态地生成接口的实现类,以满足各种应用场景的需求。这种方法可以应用于多种领域,例如 ORM 框架、分布式服务框架、AOP 等等。 在 Java 中,动态...

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

    8代表Java 8),访问标志(`ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE`表示公共、抽象和接口),接口的全名,签名(对于接口,通常是null),超类名称(对于接口也是`"java/lang/Object"`),以及接口实现列表...

    Android-Android无痕埋点框架使用ASM插桩实现

    4. **构建和加载类**: 最后,使用ASM的ClassWriter生成新的字节码,然后通过DexClassLoader或其他类加载器动态加载到Android系统中。 MonitorDemo-master项目很可能包含了一个示例的Android无痕埋点框架实现,包括...

    cglib-2.2.jar asm-tree.jar asm-commons.jar asm.jar

    3. **元编程**:ASM库允许开发者在运行时动态创建或修改类,这对于构建元编程框架或字节码级别的调试工具至关重要。 4. **字节码分析**:ASM-Tree提供了对字节码的高级抽象,便于进行代码分析和修改,对于字节码级别...

    cglib和asm

    ASM提供了底层的字节码操作能力,而CGlib则在其上构建了一个更易于使用的API,使得开发者无需直接与ASM的复杂接口打交道,就能实现类的动态扩展和代理。CGlib封装了ASM的一些细节,提供了更高级别的抽象,使得开发者...

    ASM函数监听实现(二)之打印注入函数的参数值

    接着是`asmAopGenerator.java`,这个文件可能包含了ASM库的使用,用于动态生成代理类。ASM通过`ClassWriter`和`MethodVisitor`等接口,可以生成或修改字节码。`asmAopGenerator`可能负责生成一个代理类,这个代理类...

    cglib.jar | asm.jar对应版本

    在Java中,由于无法直接对非接口实现类进行代理(JDK动态代理仅支持接口代理),所以cglib通过继承目标类的方式来创建代理对象。当一个类没有接口或者为了性能考虑不希望使用接口时,cglib就显得尤为重要。 cglib的...

    ASM4.2 DEMO

    1. 动态生成类:ASM允许你在运行时动态创建新的类和接口。这对于实现代码生成器或者运行时类型定制非常有用。例如,你可以创建一个表示数据库记录的动态类,其中包含字段和方法,这些都根据数据库表结构自动生成。 ...

    asm 6.0 工具集

    ASM库允许开发者直接操作字节码,创建和修改类,甚至在运行时动态生成类。ASM通过访问者模式设计,使得在字节码级别进行操作变得简洁高效。ASM支持JVM规范的所有版本,包括Java 8及更高版本的特性,如lambda表达式和...

    asm + cglib demo

    1. **动态代理**: 创建动态代理类,用于模拟接口的实现,比如在不修改源代码的情况下增强或拦截方法调用。 2. **代码分析**: 分析已存在的类和方法,用于性能优化、代码理解和调试。 3. **代码生成**: 动态生成新的...

    Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)

    使用JDK动态代理,我们需要实现InvocationHandler接口,然后通过Proxy类的newProxyInstance方法创建代理对象。这个方法需要传入目标接口的类加载器、接口数组以及我们实现的InvocationHandler实例。 **CGLIB**: ...

    代码生成工具asm-3.2

    3. **插件系统**:利用ASM动态生成插件类,实现灵活的插件化架构。 4. **动态语言实现**:一些动态语言的Java实现,如Groovy和Jython,使用ASM来生成Java字节码。 5. **框架开发**:例如Spring AOP和Hibernate ORM等...

    cglib包及依赖汉cglib3.1和asm4.2

    cglib包及依赖汉cglib3.1和asm4.2,主要作用是...JDK的动态代理用起来非常简单,但它有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的继承的类,该怎么办?现在我们可以使用CGLIB包

    Cglib和asm的jar包

    1. **字节码生成**:ASM允许开发者在运行时动态创建新的类和接口,或者修改已有的类。 2. **代码分析**:ASM可以解析类的字节码,帮助理解类的结构和行为,这对于调试、测试和性能分析非常有用。 3. **字节码优化**...

    asm的jar包

    4. **示例**:有时,压缩包中还会包含示例代码,演示如何使用ASM来实现某些特定功能,如创建动态代理、修改类或方法的行为等。 5. **构建脚本和配置文件**:如`pom.xml`(如果是Maven项目)或者`build.gradle`...

    ASM中文帮助文档

    - **动态代理**:通过ASM,开发者可以创建动态代理类,实现运行时接口的动态实现。 - **代码分析**:在性能调优、代码安全审计或白盒测试中,ASM能帮助解析类结构和方法体。 - **代码优化**:ASM可以用来对字节码...

    asm-2.2.1-sources.jar.zip

    - 动态代理:创建接口的代理类,使得可以在运行时动态实现这些接口并调用其方法。 - 类分析:解析类文件,获取类的结构信息,如字段、方法、注解等。 - 字节码生成:允许在运行时创建新的类或者修改现有类的字节码,...

Global site tag (gtag.js) - Google Analytics