..
运行时定时
我们在 第 4 部分中分析过的方法定时修改对于隔离性能问题来说可能一个很有用的工具 ,但它的确需要一个更灵活的接口。在该文中,我们只是将类和方法名称作为参数传递给程 序,程序加载二进制类文件,添加定时代码,然后写回该类。对于本文,我们将把代码转换 为使用加载时修改方法,并将它转换为可支持模式匹配,用以指定要定时的类和方法。
在加载类时更改代码以处理这种修改是很容易的。在清单 4 中的 javassist.Translator 代码的基础上,当正在写出的类名称与目标类名称匹配时,我们可以仅从 onWrite() 调用用 于添加定时信息的方法。清单 5 展示了这一点(没有包含 addTiming() 的全部细节――请 参阅第 4 部分以了解这些细节)。
清单 5. 在加载时添加定时代码
public class TranslateTiming
{
private static void addTiming(CtClass clas, String mname)
throws NotFoundException, CannotCompileException {
...
}
public static void main(String[] args) {
if (args.length >= 3) {
try {
// set up class loader with translator
Translator xlat =
new SimpleTranslator(args[0], args[1]);
ClassPool pool = ClassPool.getDefault(xlat);
Loader loader = new Loader(pool);
// invoke "main" method of target class
String[] pargs = new String[args.length-3];
System.arraycopy(args, 3, pargs, 0, pargs.length);
loader.run(args[2], pargs);
} catch (Throwable ex) {
ex.printStackTrace();
}
} else {
System.out.println("Usage: TranslateTiming" +
" class-name method-mname main-class args...");
}
}
public static class SimpleTranslator implements Translator
{
private String m_className;
private String m_methodName;
public SimpleTranslator(String cname, String mname) {
m_className = cname;
m_methodName = mname;
}
public void start(ClassPool pool) {}
public void onWrite(ClassPool pool, String cname)
throws NotFoundException, CannotCompileException {
if (cname.equals(m_className)) {
CtClass clas = pool.get(cname);
addTiming(clas, m_methodName);
}
}
}
}
Java编程的动态性,第5部分: 动态转换类(5)
时间:2011-04-09 IBM Dennis M. Sosnoski
模式方法
如清单 5 所示,除了使方法定时代码在加载时工作外,在指定要定时的方法时增加灵活 性也是很理想的。我最初使用 Java 1.4 java.util.regex 包中的正则表达式匹配支持来实 现这点,然后意识到它并没有真正带来我想要的那种灵活性。问题在于,用于选择要修改的 类和方法的有意义的模式种类无法很好地适应正则表达式模型。
那么哪种模式对于选择类和方法 有意义呢?我想要的是在模式中使用类和方法的任何几 个特征的能力,包括实际的类和方法名称、返回类型,以及调用参数类型。另一方面,我不 需要对名 |