java - 使用 Javassist 修改父类(super class)中声明的方法

标签 java bytecode javassist

我正在尝试使用 CtMethod#insertBefore 修改方法这是在父类(super class)中声明的。但是,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打印到控制台,但如果我调用 getConnection() AbstractTestDataSource 中声明的方法什么都没发生。 我做错了什么?

编辑

我可以确认这两种方法都已检测,因为这是打印到控制台的内容:

getConnection(Ljava/lang/String;Ljava/lang/String;)Ljava/sql/Connection;
getConnection()Ljava/sql/Connection;

最佳答案

我的解决方案是检查 getConnection 方法是否在当前类以外的类中声明。

if (!ctClass.equals(method.getDeclaringClass())) {
    method = overrideMethod(ctClass, method);
}

如果是这样,我创建(并因此重写) getConnection 方法并委托(delegate)给父类(super class)。

private CtMethod overrideMethod(CtClass ctClass, CtMethod getConnectionMethodOfSuperclass)
        throws NotFoundException, CannotCompileException {
    final CtMethod m = CtNewMethod.delegator(getConnectionMethodOfSuperclass, ctClass);
    ctClass.addMethod(m);
    return m;
}

这感觉不是理想的解决方案,但它运行良好。

关于java - 使用 Javassist 修改父类(super class)中声明的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29468741/

相关文章:

java - 编译.java文件时javac.exe做什么?

java - 什么样的 Java 代码需要堆栈映射框架?

java - 在Java中如何在执行时注入(inject)代码?

java - 使用 javassist 创建空构造函数(java)无法开始工作

没有构造函数的 Javassist 代理类

java - 在Linux中配置tomcat并运行部署的应用程序

java - 如何使用 CompletionHandlers 和小于请求的 ByteBuffer 读取请求?

java - jasperreport生成的条形码无法扫描

java - 从 Java 字节码中删除指令

java - 同一实体上的多对多关系,无需额外的连接表列