龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > JAVA开发 >

体验Java 1.5中面向(AOP)编程[组图](5)

时间:2009-12-23 15:42来源:未知 作者:admin 点击:
分享到:
public static void premain (String className, Instrumentation i) throws ClassNotFoundException, InstantiationException, IllegalAccessException { Class instClass = Class.forName(className); Instrumento

  public static void premain (String className,
  Instrumentation i)
  throws ClassNotFoundException,
  InstantiationException,
  IllegalAccessException
  {
   Class instClass = Class.forName(className);
   Instrumentor inst = (Instrumentor)instClass.newInstance();
   i.addTransformer(new InstrumentorAdaptor(inst));
  }

  我们在此处注册的适配器将充当上面给出的Instrumentor接口和Java的ClassFileTransformer接口之间的桥梁。   

  public class InstrumentorAdaptor
  implements ClassFileTransformer
  {
   public byte[] transform (ClassLoader cl,String className,Class classBeingRedefined,
  ProtectionDomain protectionDomain,byte[] classfileBuffer)
   {
    try {
     ClassParser cp =new ClassParser(new ByteArrayInputStream(classfileBuffer),className + ".java");
     JavaClass jc = cp.parse();
   ClassGen cg = new ClassGen(jc);
   for (Annotation an : getAnnotations(jc.getAttributes())) {
      instrumentor.instrumentClass(cg, an);
     }
   for (org.apache.bcel.classfile.Method m : cg.getMethods()) {
      for (Annotation an : getAnnotations(m.getAttributes())) {
       ConstantPoolGen cpg =cg.getConstantPool();
       MethodGen mg =new MethodGen(m, className, cpg);
       instrumentor.instrumentMethod(cg, mg, an);
       mg.setMaxStack();
       mg.setMaxLocals();
       cg.replaceMethod(m, mg.getMethod());
      }
     }
     JavaClass jcNew = cg.getJavaClass();
     return jcNew.getBytes();
    } catch (Exception ex) {
     throw new RuntimeException("instrumenting " + className, ex);
    }
   }
   ...
  }

  这种在启动时重构字节码的方法位于在示例的/code/03_startup目录中。

  异常的处理

  文章前面提到,我希望编写附加的代码使用不同目的的@Status注解。我们来考虑一下一些额外的需求:我们的应用程序必须捕捉所有的未处理异常并把它们显示给用户。但是,我们不是提供Java堆栈跟踪,而是显示拥有@Status注解的方法,而且还不应该显示任何代码(类或方法的名称或行号等等)。

  例如,考虑下面的堆栈跟踪信息:

  java.lang.RuntimeException: Could not load data for symbol IBM
  at boxpeeking.code.YourCode.loadData(Unknown Source)
  at boxpeeking.code.YourCode.go(Unknown Source)
  at boxpeeking.yourcode.ui.Main+2.run(Unknown Source)
  at java.lang.Thread.run(Thread.java:566)
  Caused by: java.lang.RuntimeException: Timed out
  at boxpeeking.code.YourCode.connectToDB(Unknown Source)

  ... 更多信息

  这将导致图1中所示的GUI弹出框,上面的例子假设你的YourCode.loadData()、YourCode.go()和YourCode.connectToDB()都含有@Status注解。请注意,异常的次序是相反的,因此用户最先得到的是最详细的信息。  


  
图3.显示在错误对话框中的堆栈跟踪信息

精彩图集

赞助商链接