ASM + 接口 动态生成类

简介: 好吧 ,我承认上篇文章 确认让人看不明白ASM到底有什么用,那么这篇来举个例子吧 ,比如 我制定任意的接口(接口名称,接口方法都是随意的)package com.

好吧 ,我承认上篇文章 确认让人看不明白ASM到底有什么用,那么这篇来举个例子吧 ,比如 我制定任意的接口(接口名称,接口方法都是随意的)

package com.test;

public interface ISayHello
{
    public void MethodA();
    
    public void MethodB();
    
    public void Abs();
}

 

然后我想让ASM帮我为接口生成一个继承类,并实现所有的方法,方法就 System.out.println("[当前方法名]") 虽然例子很简单,先看完

package com.test;

import java.io.FileOutputStream;
import java.lang.reflect.Method;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class InterfaceHandler extends ClassLoader implements Opcodes
{
    public static void main(final String args[]) throws Exception
    {
        ISayHello iSayHello = (ISayHello)MakeClass(ISayHello.class);
        
        iSayHello.MethodA();
        
        iSayHello.MethodB();
        
        iSayHello.Abs();
        
    }
    
    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(className);
        fos.write(code);
        fos.close();
        
        /*
         * 从文件加载类
         */
        InterfaceHandler loader = new InterfaceHandler();
        Class exampleClass = loader.defineClass(className,
            code,
            0,
            code.length);
        
        /*
         * 反射生成实例
         */
        Object obj = exampleClass.getConstructor(null).newInstance(null);
        
        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();
    }
}


好了,运行结果:

调用方法 [MethodA]
调用方法 [MethodB]
调用方法 [Abs]

如果在这个例子的基础上,让生成对象由Spring托管然后根据接口名去查找对应的 sql_ID . OK,太棒了. 不过别忘了最好还结合标注一起使用,这样可以确认哪些接口是用于 Sql滴

 


 

 

 

 

 

 

目录
相关文章
|
4月前
|
SQL Java
访问者模式问题之在ASM中,实现一个访问者来删除指定的类属性,如何解决
访问者模式问题之在ASM中,实现一个访问者来删除指定的类属性,如何解决
|
6月前
|
Java API
使用ASM为一个类增加属性工具类
使用ASM为一个类增加属性工具类
63 0
|
6月前
|
Java
使用ASM动态生成类的拦截代理类
使用ASM动态生成类的拦截代理类
77 0
|
6月前
|
Java 数据库连接 mybatis
使用ASM动态创建接口实现类
使用ASM动态创建接口实现类
52 0
|
6月前
|
Java API Android开发
ASM 框架:字节码操作的常见用法(生成类,修改类,方法插桩,方法注入)
ASM 框架:字节码操作的常见用法(生成类,修改类,方法插桩,方法注入)
117 0
|
Java
[ASM教程]#1分析类
ASM是一种通用Java字节码操作和分析框架,它可以用于修改现有的class文件或动态生成class文件。
144 0
[ASM教程]#3增加移除类成员
可以委托一个ClassWriter。
80 0
[ASM教程]#2生成类
使用classWriter生成类
73 0
|
存储 Java API
ASM 关键接口 MethodVisitor
ASM 关键接口 MethodVisitor
440 0
ASM 关键接口 MethodVisitor
|
存储 Java 计算机视觉
ASM - TreeApi Method组件和接口简介
ASM - TreeApi Method组件和接口简介
227 0