当前位置: 首页 > 知识库问答 >
问题:

如何使用bytebuddy截取具有特定参数的方法

刁丰羽
2023-03-14

我想截获名为methodA的方法,其中一个参数的类型是String as blow,我应该怎么做。如何使用hasParameters()api?

public class Demo {

    public static void main(String[] args) {

        new ByteBuddy()
                .subclass(A.class)
                .method(named("methodA").and(hasParameters(?)))
    }


    static class A {

        public void methodA() {
            System.out.println("methodA() invoked.");
        }

        public void methodA(String arg) {
            System.out.println("methodA(" + arg + ") invoked.");
        }
    }

}

共有2个答案

郑燕七
2023-03-14

为了澄清,您需要定义一个匹配器(类似于过滤器)来应用于方法。在匹配器中创建一些约束,使其仅与指定的某些参数结构匹配:

ElementMatcher<Iterable<? extends ParameterDescription>> matcher = parameterDescriptions -> {
    for (ParameterDescription p : parameterDescriptions) {
        if (p.getType().equals(TypeDescription.STRING.asGenericType()) && p.getIndex() == 0) return true;
    }
    return false;
};

ByteBuddyAgent.install();
new ByteBuddy()
    .redefine(SomeType.class)
    .method(ElementMatchers.hasParameters(matcher))
    .intercept(FixedValue.value("Hello World"))
    .make()
    .load(SomeType.class.getClassLoader(), 
        ClassReloadingStrategy.fromInstalledAgent());
怀齐智
2023-03-14

为此,您需要ElementMatchers.takes参数(String.class)匹配器。

比如说:

    Class<? extends A> loaded =  new ByteBuddy().subclass(A.class)
       .method(ElementMatchers.named("methodA").and(ElementMatchers.takesArguments(String.class)))
       .intercept(MethodDelegation.to(Demo.class))
       .make().load(Demo.class.getClassLoader(), ClassLoadingStrategy.Default.INJECTION).getLoaded();

    A instance = loaded.getConstructor().newInstance();
    instance.methodA("abc");
    instance.methodA();


public class Demo {

    static void intercept(String arg){
         System.out.println("intercepted");
    }
}
 类似资料:
  • 我知道如何使用Volley GET方法进行登录,但如果我需要指定一个特定的“id”,该怎么办?我使用intent将列表项的“id”从远程数据库传递给另一个活动。putExtra。在下一个活动中,我将如何利用凌空的GET方法来解析和显示另一个表中使用传递的“id”的数据? 在浏览器中,我可以使用以下内容获得具有指定url和参数的响应: 但是我不知道如何将该url传递给Volley请求并在listvi

  • 我想截取在一个类的所有实例上调用的每个setter方法,然后在另一个类对象上调用一个方法,参数对应于第一个类的每个实例的一些字段值。为此,我想使用ByteBuddy API,但我也想为指定类的所有实例只创建一个子类 例如,我编写了以下代码: 我将为每个资源类型创建的每个子类保存在映射中,以便为每个资源类型只创建一个子类。这里的问题是,对于创建的子类的所有实例,传递给在目标对象上调用的方法“upda

  • 问题内容: 我正在扩展一个类并覆盖一个方法。我要做的只是调用super,但是调用了一个经过修改的参数,该参数被其方法之一拦截。一个例子使它更加清楚: 我宁愿使用不需要自己的编译器的工具。最佳选择是什么? 问题答案: 鉴于这是一个接口,您可以考虑使用动态代理,该代理将: 包装原始foo 拦截所有消息并将其转发给原始foo 上面的链接中有一个完整的示例。这只是想法: 请注意,如果不是接口,您仍可以手动

  • 让我有一个这样的界面: 还有这样一个实现类: 现在我想使用bytebuddy创建一个拦截器/代理,它捕捉对setter的调用,存储更改后的值,并调用real方法。 最后,我想向拦截器/代理“询问”被调用的setter和更改的值。 我尝试了很多考虑也教程,但到目前为止,我发现没有工作的解决方案。也许有人可以帮助我。 这是拦截器: 以下是我当前的“测试”代码: 编辑:

  • 让我们有一个简单的界面: 现在我这样创建代理: 当我执行测试时,我看到以下输出: 似乎我永远无法访问被调用方法的方法签名,如果它起源于接口,并且不是由超类实现的?! 当我调用我会看到,它也接受所有输入参数。 我错过了什么?我看了留档,但我仍然很困惑。 一般来说,我想创建,它捕获代理类中的所有方法,并处理以下情况: 执行一些操作,然后将调用传播到原始方法 做某事并返回它自己的结果,而不调用原始meh

  • 我想忽略对源类和目标对象抽象的方法的检测,但是如果它只是源的抽象方法,那么我想在目标对象上调用等价的方法。目前我正在使用这个 但是得到这些类型的异常 在源类和目标对象中都没有实现的抽象方法失败并出现以下错误。 无法调用公共抽象java.lang.Objectjava.sql.Wraper.unwrap(java.lang.Class)throws java.sql。公共静态易失性java.lang