使用Javassist修改在超类中声明的方法

费利克斯

我正在尝试修改CtMethod#insertBefore在超类中声明的方法但是,使用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方法并将其委托给超类。

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

感觉不是理想的解决方案,但效果很好。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用Javassist修改在超类中声明的方法

来自分类Dev

Javassist 不调用超类中定义的方法

来自分类Dev

通过在超类中声明的方法实现协议?

来自分类Dev

使用Javassist获取类中已声明字段的索引以用于字节码

来自分类Dev

修改其他类中声明的对象的最佳方法(Java)

来自分类Dev

使用 Javassist 修改后检测加载的类

来自分类Dev

无法使用Javassist更新类方法

来自分类Dev

在超类方法中修改子类的不可变/受保护的变量

来自分类Dev

在超类和方法调用中声明一个子类

来自分类Dev

如何使用C#中的公共超类修改对象列表的成员?

来自分类Dev

为什么模块调用的块不能修改在Ruby中实现类的对象?

来自分类Dev

覆盖超类中的方法

来自分类Dev

使用Javassist记录方法调用和参数值,如何使记录器类在每个检测类中可见?

来自分类Dev

JAXB:在超类中声明的字段的注释在子类中不同

来自分类Dev

修改扩展类中的方法

来自分类Dev

在子类的方法中本地调用超类方法时,使用“ super”关键字还是使用超类实例?

来自分类Dev

在Haxe中,当未在“抽象”超类中定义子类时,如何在子类中强制执行方法声明?

来自分类Dev

使用python中的类方法修改对象的属性

来自分类Dev

类文件中的方法声明

来自分类Dev

在类或方法中声明String

来自分类Dev

使用RubyInline声明类方法

来自分类Dev

在 monad 实例声明中使用 monad 超类?

来自分类Dev

在类中声明了char数组后,如何修改它?

来自分类Dev

如何使用Roslyn正确修改类声明语法?

来自分类Dev

Redux withRouter在超类的静态方法中

来自分类Dev

在多重继承中调用超类方法

来自分类Dev

在scala中调用超类apply方法

来自分类Dev

在类的方法之一中的switch语句中使用在类中声明的int

来自分类Dev

使用方法创建超类

Related 相关文章

  1. 1

    使用Javassist修改在超类中声明的方法

  2. 2

    Javassist 不调用超类中定义的方法

  3. 3

    通过在超类中声明的方法实现协议?

  4. 4

    使用Javassist获取类中已声明字段的索引以用于字节码

  5. 5

    修改其他类中声明的对象的最佳方法(Java)

  6. 6

    使用 Javassist 修改后检测加载的类

  7. 7

    无法使用Javassist更新类方法

  8. 8

    在超类方法中修改子类的不可变/受保护的变量

  9. 9

    在超类和方法调用中声明一个子类

  10. 10

    如何使用C#中的公共超类修改对象列表的成员?

  11. 11

    为什么模块调用的块不能修改在Ruby中实现类的对象?

  12. 12

    覆盖超类中的方法

  13. 13

    使用Javassist记录方法调用和参数值,如何使记录器类在每个检测类中可见?

  14. 14

    JAXB:在超类中声明的字段的注释在子类中不同

  15. 15

    修改扩展类中的方法

  16. 16

    在子类的方法中本地调用超类方法时,使用“ super”关键字还是使用超类实例?

  17. 17

    在Haxe中,当未在“抽象”超类中定义子类时,如何在子类中强制执行方法声明?

  18. 18

    使用python中的类方法修改对象的属性

  19. 19

    类文件中的方法声明

  20. 20

    在类或方法中声明String

  21. 21

    使用RubyInline声明类方法

  22. 22

    在 monad 实例声明中使用 monad 超类?

  23. 23

    在类中声明了char数组后,如何修改它?

  24. 24

    如何使用Roslyn正确修改类声明语法?

  25. 25

    Redux withRouter在超类的静态方法中

  26. 26

    在多重继承中调用超类方法

  27. 27

    在scala中调用超类apply方法

  28. 28

    在类的方法之一中的switch语句中使用在类中声明的int

  29. 29

    使用方法创建超类

热门标签

归档