`
15606915740
  • 浏览: 20095 次
  • 性别: Icon_minigender_1
  • 来自: 厦门
文章分类
社区版块
存档分类
最新评论

通过spring asm 操作字节码生成属性get和set方法

 
阅读更多
   public static void strongClass() throws Exception{
        String myPath = "file:/D:/test/class/MyMain.class";
        System.out.println(myPath);
        byte[] cLassBytes = null;
        Path path = null;
        try {
            path = Paths.get(new URI(myPath));
            cLassBytes = Files.readAllBytes(path);
            System.out.println("========bytes size =======" + cLassBytes.length);
            //spring asm的包
            ClassReader cr = new ClassReader(cLassBytes);
            jdk.internal.org.objectweb.asm.ClassReader jcr = new jdk.internal.org.objectweb.asm.ClassReader(cLassBytes);
            //jdk rt.jar中的包
            ClassNode cn = new ClassNode();
            jcr.accept(cn,0);
            List<FieldNode> fields = cn.fields;
            //spring asm的包
            ClassWriter cw = new ClassWriter(cr,ClassWriter.COMPUTE_MAXS);
            cr.accept(cw, Opcodes.ASM5);
            MethodVisitor mv = null;
            for(FieldNode n : fields){
            String fieldName = n.name;
            String typeOf = n.desc;
                System.out.println(typeOf);
            // getMethod  StringUtils也是用spring core中的工具包
            String getMethodName = "get" + StringUtils.capitalize(fieldName);
                //第一个参数是方法的访问权限(public,private等)
                //第二个参数是方法名(<init>是构造函数的)
                //第三个参数是返回类型(()V是没有返回值)
                //第四个参数是和泛型相关的, 这里传入null表示该方法不是泛型方法
                //第五个参数指定方法声明可能抛出的异常。 这里无异常声明抛出
            mv = cw.visitMethod(ACC_PUBLIC, getMethodName, "()" + typeOf, null, null);
                //生成方法中的代码
            mv.visitCode();
            //调用visitVarInsn方法,生成aload指令, 将第0个本地变量(也就是this)压入操作数栈。
            mv.visitVarInsn(ALOAD, 0);
                //调用visiFieldInsn是将属性压入栈
            mv.visitFieldInsn(GETFIELD, "MyMain", fieldName, typeOf);
                //调用visitInsn方法,生成return指令, 方法返回
            mv.visitInsn(loadAndReturnOf(typeOf)[1]);
                //调用visitMaxs方法, 指定当前要生成的方法的最大局部变量和最大操作数栈
            mv.visitMaxs(2, 1);
                //最后调用visitEnd方法, 表示当前要生成的构造方法已经创建完成
            mv.visitEnd();

                String setMethodName = "set" + StringUtils.capitalize(fieldName);
                mv = cw.visitMethod(ACC_PUBLIC, setMethodName, "(" + typeOf + ")V", null, null);
                mv.visitCode();
                mv.visitVarInsn(ALOAD, 0);
                mv.visitVarInsn(loadAndReturnOf(typeOf)[0], 1);
                mv.visitFieldInsn(PUTFIELD, "MyMain", fieldName, typeOf);
                mv.visitInsn(RETURN);
                mv.visitMaxs(3, 3);
                mv.visitEnd();
            }
            byte[] bs = cw.toByteArray();
            cLassBytes = bs;
            System.out.println("========bytes size =======" + bs.length + cLassBytes.length);
            FileOutputStream fos = new FileOutputStream("E:/daemon1/MyMain.class");
            fos.write(cLassBytes);
            fos.flush();
            fos.close();
        } catch (IOException | URISyntaxException e) {
            e.printStackTrace();
        }
//        Class clz = new SynamicCompiler().defineClass("MyMain", cLassBytes, 0, cLassBytes.length);
//        Method method = clz.getMethod("getRedisUtil");
//        Method setMethod = clz.getMethod("setRedisUtil",RedisUtil.class);
//        Object obj = clz.newInstance();
//        setMethod.invoke(obj,new RedisUtil());
//        RedisUtil redisUtil = (RedisUtil) method.invoke(obj);
//        System.out.println(redisUtil);
       // Thread.sleep(5000);
    }
    //返回的都是字节码的指令,需要清楚字节码
    private static int[] loadAndReturnOf(String typeof) {
        System.out.println(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};
        }
    }
分享到:
评论

相关推荐

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

    3. **MethodVisitor**: 这是用来访问和修改方法的接口,包括方法的访问标志、返回类型、参数类型、局部变量表和字节码指令。 4. **FieldVisitor**: 类似于MethodVisitor,但用于处理类的字段信息。 5. **Opcode**:...

    ASM字节码操作简单实例

    ASM字节码库是Java字节码操作的强大工具,它允许程序员在运行时动态生成类或者增强已有类的功能。在本实例中,我们将探讨如何利用ASM实现简单的面向切面编程(AOP)功能,这是一种在不修改源代码的情况下,添加额外...

    Android-埋点计时Gradle插件利用ASM插入字节码

    3. 插入字节码:对于每个符合条件的方法,ASM会在其开始和结束处插入计时代码,计算并记录方法的执行时间。 4. 打印日志:在应用运行时,这些插入的计时代码会输出到控制台,开发者可以通过查看日志来分析性能。 这...

    ASM Java字节码操作框架

    ASM Java字节码操作框架PPT,结合已有AOP实现方法,对比所有对Java字节码操作方法做比较

    cglib,字节码生成库是生成和转换Java字节码的高级API。它被aop、测试、数据访问框架用来生成动态代理对象和拦截字段访问。.zip

    CGlib库利用ASM库(一个底层的Java字节码操作和分析框架)来生成和修改字节码。通过这种方式,开发者可以在程序运行时动态地创建新的类或修改现有类的行为,而无需重新编译源代码。 **动态代理** CGlib常用于实现...

    ASM 字节码修改工具中文帮助手册

    - 方法表示:通过 `AsmMethod` 等类来表示和操作方法结构。 - **工具**: - **Type**: 提供了类型描述符和类型操作相关的工具类。 - **TraceClassVisitor**: 输出字节码解析过程的追踪信息。 - **...

    Java字节码和asm入门资料

    ASM是一个开源的Java字节码操控和分析框架,它可以直接用来生成和修改Java类文件,是Java动态代理和字节码增强技术的重要工具。在深入学习Java字节码和ASM之前,我们需要先理解Java编译和运行的基本过程。 1. **...

    cglibJava字节码生成库

    2. **cglib工作原理**:cglib库通过ASM库(一个底层的Java字节码操纵框架)来实现字节码的生成。它创建了一个目标类的子类,并覆盖其方法,从而实现对原类的增强。当需要实例化目标类时,实际上是在实例化它的子类,...

    org.springframework.asm-3.0.5.RELEASE.jar

    ASM库是Spring用来动态生成和修改Java字节码的核心工具,对于理解Spring的底层机制具有重要意义。 一、ASM库简介 ASM是一个轻量级的Java字节码操控和分析框架,它可以直接生成和读取Java类的字节码。ASM提供了一种...

    java字节码框架ASM操作字节码的方法浅析

    Java字节码框架ASM是一个强大的库,它允许程序员在运行时动态生成和修改Java类和接口的字节码。ASM提供了对JVM字节码的底层访问,这使得开发者能够实现诸如AOP(面向切面编程)或者元编程等高级功能。 首先,我们...

    [字节码系列]ObjectWeb ASM构建Method Monitor

    ASM提供了一个简单的API来处理这些复杂性,但开发者仍需具备一定的JVM和字节码知识。一旦掌握,ASM就能成为强大的工具,让我们能够以编程方式控制和改变Java应用程序的行为。 通过阅读《[ayufox.iteye....

    演示Asm字节码插桩asmd-demo-master.zip

    2. **字节码解析与生成**:这部分代码会使用ClassReader和ClassWriter来读取原始字节码,通过自定义的Visitor进行处理后,由ClassWriter生成新的字节码。 3. **测试用例**:项目中可能包含一些测试类,用来验证插桩...

    Android字节码插桩

    ASM提供了一种低级别的API,允许开发者直接操作字节码,因此可以用来创建复杂的类转换器和字节码生成器。在Android开发中,ASM常用于动态代理、AOP(面向切面编程)和插桩技术。 **字节码插桩** 字节码插桩是...

    Java字节码实现Aop

    在Java中,AOP通常通过代理模式和字节码操作来实现,如Spring AOP就是其中的典型代表。本文将深入探讨如何利用字节码技术实现AOP。 首先,理解字节码是关键。Java源代码编译后生成的是字节码(.class文件),这是...

    Spring源码导入Eclipse缺失Jar包spring-asm-repack-5.0.4+spring-cglib-repack-3.1

    Spring框架在运行时对字节码进行操作,以实现AOP(面向切面编程)功能,比如代理、方法增强等。ASM库的repack版本是为了避免与应用中可能存在的其他ASM版本冲突,确保Spring的正常工作。 其次,CGLIB(Code ...

    代码生成工具asm-3.2

    同时,理解JVM的工作原理和字节码指令集也是必要的,这将有助于更好地利用ASM进行字节码操作。 **总结** ASM-3.2作为一个强大的代码生成工具,为开发者提供了深入控制Java字节码的能力,广泛应用于各种复杂场景。...

    字节码实战包含class,字节码.zip

    Java的安全模型部分基于字节码,例如,类加载器和字节码验证器检查字节码以防止恶意代码执行。 综上所述,"字节码实战"涵盖了Java开发中的核心概念和技术,包括字节码的生成、解析、优化以及其在各种高级技术中的...

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

    ASM是一个低级别的库,可以直接操作Java字节码,提供了一种动态生成和修改类的方法。它通过ClassWriter、ClassReader、MethodVisitor等接口,允许开发者对字节码进行读取、修改和写入。ASM的核心在于它的事件驱动...

    cglib和asm

    CGlib和ASM是Java开发中两个非常重要的库,主要用于字节码操作和动态代理。这两个库在Java生态系统中扮演着不可或缺的角色,特别是在AOP(面向切面编程)和ORM(对象关系映射)框架中。 CGlib是一个强大的、高性能...

    JAVA字节码操作库 BCEL

    3. **字节码操作**:通过BCEL,开发者可以对字节码进行读取、解析、创建、修改和写回。例如,可以添加或删除方法、修改方法体内的指令序列、改变类的访问修饰符等。 **二、BCEL的主要功能** 1. **类分析**:BCEL...

Global site tag (gtag.js) - Google Analytics