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

Bytebuddy:是否可以通过用lambda表达式替换执行来拦截方法?

益清野
2023-03-14

是否可以通过用lambda表达式或其他类的非静态方法替换执行来拦截方法?

例1:

installByteBuddyAgent();

byteBuddy
        .redefine(sourceClass) //This is important, i need to change a class definition
        .method(named(methodName))
        .intercept({{expression}})
        .make()
        .load(
                sourceClass.getClassLoader(),
                ClassReloadingStrategy.fromInstalledAgent());

//expression = Lambda expression that would be executed in place of the original method, or call a (non-static) method from some other class.

其目的是避免使用静态方法编写类来执行拦截。

例2:

    public class A {
        public void sayHello() {
            System.out.println("Hello");
        }
    }

    public class B {
        public void sayGoodbye() {
            System.out.println("Goodbye");
        }
    }
    
// ...

    @Test
    void interceptAReplacingByB() {
        final Class<A> sourceClass = A.class;
        final B b = Mockito.spy(new B());
        
        byteBuddy
                .redefine(sourceClass)
                .method(named("sayHello"))
                .intercept( /*call sayGoodbye from B or create a lambda expression to do it*/ )
                .make()
                .load(
                        sourceClass.getClassLoader(),
                        ClassReloadingStrategy.fromInstalledAgent());
        
        new A().sayHello();
        
        Mockito.verify(b).sayGoodbye();
    }

代码段不代表完整的场景。它只是为了举例说明这个问题。

截取公共方法可以通过其他方式完成,但目标不是仅使用公共方法,或仅使用测试场景。

共有1个答案

詹弘毅
2023-03-14

如果我对你的理解正确:

// ...
.intercept(net.bytebuddy.implementation.MethodCall.invoke("sayGoodbye").on(b))
// ...

请注意,将在重新实现a时定义一个static字段,以保存b实例

 类似资料:
  • 问题内容: 昨晚我在玩Java8 Lambda,我想知道是否有可能在运行时检索Lambda表达式。简而言之,据我所知,Lambda表达式在运行时被转换为(静态)方法,然后使用InvokeDynamics进行调用。 让我们举一个这样的例子: 其中将是以a 作为参数的自定义方法。在此方法内部,在这种情况下,如何以类似于Lambda表达式()的形式检索参数? 我尝试使用ASM5_BETA读取参数类的生成

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

  • 问题内容: 假设我有一个通用接口: 和方法sort: 我可以调用此方法并将lambda表达式作为参数传递: 那会很好的。 但是现在,如果我将接口设为非泛型,并且将方法设为泛型: 然后像这样调用: 它不会编译。它在lambda表达式中显示错误: “目标方法是通用的” 好的,当我使用编译时,它显示以下错误: 从此错误消息看来,编译器似乎无法推断类型参数。是这样吗 如果是,那为什么会这样呢? 我尝试了各

  • 问题内容: 我在Java 8映射操作中传递了一个Function,Intellij告诉我可以将其替换为lambda表达式。但是我不知道如何在不创建中间对象结构的情况下做到这一点。 这是我的工作: 我认为Intellij建议我这样做: 我不知道一种干净的方法来获取在匿名函数中检索到的objectType.getTempUrl()。getFullUrl()部分,有什么建议吗? 问题答案: 你总是可以写

  • 我最近接触了Java8,我正在尝试学习Lambda表达式。我想做一些图形计算,我的代码到目前为止: 所有这些代码都是用于图形的,除了和使用的操作之外,所有内容都是基本的数学(加、减、乘、模),并且可以单独针对每个像素执行。 现在的问题是:有可能在GPU上运行这个吗?或者这甚至是自动基于GPU的?(我记得在什么地方读到过这个,但我不确定)