使用javassist动态注入代码

    技术2022-05-11  60

    关于java字节码的处理,目前有很多工具,如bcel,asm。不过这些都需要直接跟虚拟机指令打交道。如果你不想了解虚拟机指令,可以采用javassist。javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。     下面通过一个简单的例子,通过javassist来实现如何动态注入代码。     假设,存在类A,如下: public class A {     public void method() {         for (int i = 0; i < 1000000; i++) {         }         System.out.println("method1");     } } 测试类B如下: public class B {     public static void main(String[] args) {         A a = new A();         a.method();        } } 现在想统计一下method的执行时间, 默认的实现是修改method:  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方法:     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还提供了很多的功能,用于更改类结构。有兴趣的可以参考相关文档  

    最新回复(0)