【问题标题】:Bytebuddy: Is it possible to intercept a method by replacing the execution with a lambda expression?Bytebuddy:是否可以通过用 lambda 表达式替换执行来拦截方法?
【发布时间】:2021-03-25 13:14:51
【问题描述】:

是否可以通过将执行替换为 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();
    }

此代码 sn-p 并不代表完整的场景。它只是为了举例说明问题。

可以通过其他方式拦截公共方法,但目标不是只与公共方法一起工作,或者只与测试场景一起工作。

【问题讨论】:

  • 我不确定你想要什么。也许,您想使用InvocationHandlerAdapter.of(InvocationHandler)。由于InvocationHandler 是一个函数式接口,您可以使用 lambda 表达式来实现它。
  • 我再举一个例子来解释我想要研究的假设。谢谢。

标签: java bytecode byte-buddy


【解决方案1】:

如果我的解释是正确的:

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

注意a static field will be defined in your reimplementation of A to hold the instance of b

【讨论】:

  • Error invoking java.lang.instrument.Instrumentation#retransformClasses java.lang.IllegalStateException: Error invoking java.lang.instrument.Instrumentation#retransformClasses ... ... 原因:java.lang.UnsupportedOperationException :类重新定义失败:试图更改架构(添加/删除字段)
  • 祝你好运。我看到您正在将重新定义类与代理混合,这是我没有经验的用例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
  • 1970-01-01
  • 2018-02-24
  • 2013-03-15
相关资源
最近更新 更多