我试图修改在超类中声明的方法CtMethod#insertBefore
。但是,Javassist似乎不可能。修改Javassist在超类中声明的方法
private class AbstractTestDataSource {
public Connection getConnection() throws SQLException {
return connection;
}
}
private class TestDataSource extends AbstractTestDataSource implements DataSource {
public Connection getConnection(String username, String password) throws SQLException {
return connection;
}
// other methods omitted
}
这是我ClassFileTransformer
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer)
throws Exception {
if (!className.equals("org/example/TestDataSource")) {
return classfileBuffer;
}
final CtClass ctClass = createCtClass(loader, classfileBuffer);
for (CtMethod method : ctClass.getMethods()) {
if (method.getName().equals("getConnection")) {
System.out.print(method.getName());
System.out.println(method.getSignature());
method.insertBefore("System.out.println(\"foo\");");
}
}
return ctClass.toBytecode();
}
当我打电话getConnection(String, String)
方法,foo
被打印到控制台,但如果我认为这种声明在AbstractTestDataSource
没有任何反应getConnection()
方法。 我在做什么错?
编辑
我可以证实,这两种方法都仪器,因为这是被打印到控制台:
getConnection(Ljava/lang/String;Ljava/lang/String;)Ljava/sql/Connection;
getConnection()Ljava/sql/Connection;
你已经确定insertBefore被调用了两次,但你没有检查它实际被调用的是什么。尝试打印方法名称和描述符。更好的是,看看你是否可以获得目标类的实际类文件并反汇编它。 – Antimony 2015-04-06 14:34:59
好吧,我想我知道问题在哪里。超类没有被修改,因为在transform方法中,我只能转换当前加载的一个类。我想我现在的选择是重新转换超类或动态覆盖超类方法。现在尝试后一种选择... – Felix 2015-04-06 14:54:54