当前位置:编程学习 > JAVA >>

使用ASM4.0实现AOP的功能,监控每个方法的执行时间

 AOP的更通用的做法是对原始类动态生成子类,调用子类的方法覆盖父类,来实现AOP的功能。著名的 Hibernate 和 Spring 框架,就是使用这种技术实现了 AOP 的“无损注入”。
 
下面我们就通过一个示例来对方法Foo.execute调用时动态注入方法执行前后的时间统计来统计方法的执行时间

[java] 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
 
import org.objectweb.asm.ClassReader; 
import org.objectweb.asm.ClassVisitor; 
import org.objectweb.asm.ClassWriter; 
import org.objectweb.asm.MethodVisitor; 
import org.objectweb.asm.Opcodes; 
 
public class AsmAopExample extends ClassLoader implements Opcodes{ 
     
    public static  class Foo { 
        public static void execute() { 
            System.out.println("test changed method name"); 
            try { 
                Thread.sleep(10); 
            } catch (InterruptedException e) { 
                // TODO Auto-generated catch block 
                e.printStackTrace(); 
            } 
        } 
    } 
     
    public static class Monitor{ 
         
        static long start = 0; 
         
        public static void start(){ 
            start = System.currentTimeMillis(); 
        } 
        public static void end(){ 
            long end = System.currentTimeMillis(); 
            System.out.println("execute method use time :" + (end - start)); 
        } 
    } 
 
    public static void main(String[] args) throws IOException, IllegalArgumentException, SecurityException, IllegalAccessException, InvocationTargetException { 
         
        ClassReader cr = new ClassReader(Foo.class.getName()); 
        ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS); 
        ClassVisitor cv = new MethodChangeClassAdapter(cw); 
        cr.accept(cv, Opcodes.ASM4); 
 
        // gets the bytecode of the Example class, and loads it dynamically 
        byte[] code = cw.toByteArray(); 
 
 
        AsmAopExample loader = new AsmAopExample(); 
        Class<?> exampleClass = loader.defineClass(Foo.class.getName(), code, 0, code.length); 
 
        for(Method method:  exampleClass.getMethods()){ 
            System.out.println(method); 
        } 
         
        exampleClass.getMethods()[0].invoke(null, null);  //調用execute,修改方法內容 
         
         
        // gets the bytecode of the Example class, and loads it dynamically 
 
        FileOutputStream fos = new FileOutputStream("e:\\logs\\Example.class"); 
        fos.write(code); 
        fos.close(); 
    } 
     
    static class MethodChangeClassAdapter extends ClassVisitor implements Opcodes { 
 
        public MethodChangeClassAdapter(final ClassVisitor cv) { 
            super(Opcodes.ASM4, cv); 
        } 
 
        @Override 
        public MethodVisitor visitMethod( 
            int access, 
            String name, 
            String desc, 
            String signature, 
            String[] exceptions) 
        { 
            if("execute".equals(name))  //此处的execute即为需要修改的方法  ,修改方法內容 
            {   
                MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);//先得到原始的方法   
                MethodVisitor newMethod = null;   
                newMethod = new AsmMethodVisit(mv); //访问需要修改的方法   
                return newMethod;   
            }   
             
            return null; 
        } 
 
 
    } 
     
     static  class AsmMethodVisit extends MethodVisitor { 
 
        public AsmMethodVisit(MethodVisitor mv) { 
            super(Opcodes.ASM4, mv);     
 &nb

补充:软件开发 , Java ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,