`

使用javassist动态注入代码

    博客分类:
  • j2se
 
阅读更多
关于java字节码的处理,目前有很多工具,如bcel,asm。不过这些都需要直接跟虚拟机指令打交道。如果你不想了解虚拟机指令,可以采用javassist。javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。
    下面通过一个简单的例子,通过javassist来实现如何动态注入代码。
    假设,存在类A,如下:
java 代码


    public class A { 
        public void method() { 
            for (int i = 0; i < 1000000; i++) { 
            } 
            System.out.println("method1"); 
        } 
    } 


测试类B如下:
java 代码


    public class B { 
        public static void main(String[] args) { 
            A a = new A(); 
            a.method();    
        } 
    } 


现在想统计一下method的执行时间,
默认的实现是修改method:

java 代码


    public void method() { 
            long start = System.currentTimeMillis(); 
            for (int i = 0; i < 1000000; i++) { 
            } 
            System.out.println("method1"); 
            long end = System.currentTimeMillis(); 
            System.out.println(end - start); 
        } 


如果A的方法很多,统计方法的执行时间的代码就会相应的增加。为了减少工作量,通过动态注入代码的形式来实现。
修改B的main方法:

java 代码


    public static void main(String[] args) throws Exception { 
        //用于取得字节码类,必须在当前的classpath中,使用全称 
          CtClass ctClass = ClassPool.getDefault().get("org.esoft.A"); 
           //需要修改的方法名称 
          String mname = "method";        
          CtMethod mold = ctClass.getDeclaredMethod(mname); 
           //修改原有的方法名称 
          String nname = mname + "$impl"; 
          mold.setName(nname); 
           //创建新的方法,复制原来的方法 
          CtMethod mnew = CtNewMethod.copy(mold, mname, ctClass, null); 
           //主要的注入代码 
          StringBuffer body = new StringBuffer(); 
          body.append("{\nlong start = System.currentTimeMillis();\n"); 
          //调用原有代码,类似于method();($$)表示所有的参数 
          body.append(nname + "($$);\n"); 
          body.append("System.out.println(\"Call to method " 
                      + mname 
                      + " took \" +\n (System.currentTimeMillis()-start) + " 
                      + "\" ms.\");\n"); 
         
          body.append("}"); 
           //替换新方法 
          mnew.setBody(body.toString()); 
           //增加新方法 
          ctClass.addMethod(mnew); 
          //类已经更改,注意不能使用A a=new A();,因为在同一个classloader中,不允许装载同一个类两次 
          A a=(A)ctClass.toClass().newInstance(); 
          a.method(); 
      } 

分享到:
评论

相关推荐

    Javassist代码注入

    javassist实现代码注入,详细内容可以参考;https://blog.csdn.net/xiangzhihong8/article/details/83060674

    使用javassist修改class文件.pdf

    使用javassist修改class文件.pdf

    javassist.jar源码

    javassist-3.7.ga.jar反射类javassist.jar源码

    开发工具 javassist-3.21.0-GA

    开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发...

    javassist-3.19.0-GA-API文档-中文版.zip

    赠送源代码:javassist-3.19.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.19.0-GA.pom; 包含翻译后的API文档:javassist-3.19.0-GA-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.javassist:...

    javassist-3.14.0-GA

    它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态AOP框架。 关于java字节码的处理,目前有很多工具,如bcel,asm。不过这些都需要直接跟虚拟机指令打交道。如果你不想了解...

    javassist-3.23.1-GA-API文档-中文版.zip

    赠送源代码:javassist-3.23.1-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.23.1-GA.pom; 包含翻译后的API文档:javassist-3.23.1-GA-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.javassist:...

    Javassistjar包

    它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态"AOP"框架。 关于java字节码的处理,目前有很多工具,如bcel,asm。不过这些都需要直接跟虚拟机指令打交道。如果你不想了解...

    javassist-3.24.0-GA-API文档-中文版.zip

    赠送源代码:javassist-3.24.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.24.0-GA.pom; 包含翻译后的API文档:javassist-3.24.0-GA-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.javassist:...

    javassist-3.27.0-GA-API文档-中英对照版.zip

    赠送源代码:javassist-3.27.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.27.0-GA.pom; 包含翻译后的API文档:javassist-3.27.0-GA-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org....

    javassist反射工具

    它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态AOP框架。 关于java字节码的处理,目前有很多工具,如bcel,asm。不过这些都需要直接跟虚拟机指令打交道。如果你不想了解...

    javassist-3.24.0-GA-API文档-中英对照版.zip

    赠送源代码:javassist-3.24.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.24.0-GA.pom; 包含翻译后的API文档:javassist-3.24.0-GA-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org....

    javassist-3.23.1-GA-API文档-中英对照版.zip

    赠送源代码:javassist-3.23.1-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.23.1-GA.pom; 包含翻译后的API文档:javassist-3.23.1-GA-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org....

    javassist-3.21.0-GA-API文档-中文版.zip

    赠送源代码:javassist-3.21.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.21.0-GA.pom; 包含翻译后的API文档:javassist-3.21.0-GA-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.javassist:...

    javassist-3.20.0-GA-API文档-中文版.zip

    赠送源代码:javassist-3.20.0-GA-sources.jar; 包含翻译后的API文档:javassist-3.20.0-GA-javadoc-API文档-中文(简体)版.zip 对应Maven信息:groupId:org.javassist,artifactId:javassist,version:3.20.0-...

    动态代理-jdk、cglib、javassist.zip

    动态代理-jdk、cglib、javassist

    javassistDemo

    javassistDemo代码-------Charles破解

    Android代码-javassist

    Javassist version 3 Copyright (C) 1999-2018 by Shigeru Chiba, All rights reserved. Javassist (JAVA programming ASSISTant) makes Java bytecode manipulation simple. It is a class library for editing ...

    javassist-3.18.1-GA-API文档-中英对照版.zip

    赠送源代码:javassist-3.18.1-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.18.1-GA.pom; 包含翻译后的API文档:javassist-3.18.1-GA-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org....

    javassist-3.18.1-GA-API文档-中文版.zip

    赠送源代码:javassist-3.18.1-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.18.1-GA.pom; 包含翻译后的API文档:javassist-3.18.1-GA-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.javassist:...

Global site tag (gtag.js) - Google Analytics