【问题标题】:Redefine a specific instance with ByteBuddy使用 ByteBuddy 重新定义特定实例
【发布时间】:2021-05-04 10:30:24
【问题描述】:

我对 ByteBuddy 很陌生,这里可能缺少一些要点。

我想重新定义一个特定的实例或更精确的 Type 实例,这些实例在一个特定的类中用 ByteBuddy 实例化。

因此,如果我有一个声明类型 C 的变量的类 A 和一个也声明变量 C 的类 B,我只想重新定义在 A 中创建的实例并将原始实现保留在 B 中。(例如,只需重新定义通过等号检查的对象 / object == object)

我尝试了以下方法,但它不起作用,因为等于检查是针对 TypeDescription 而不是针对 ElementMatcher.is() 方法中的对象:

Object myObject = new Object();
    new AgentBuilder.Default()
                    .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
                    .with(AgentBuilder.Listener.StreamWriting.toSystemError().withTransformationsOnly())
                    .disableClassFormatChanges()
                    .type(ElementMatchers.is(Object.class))
                    .and(ElementMatchers.is(myObject))
                    .transform((builder, typeDescription, classLoader, module) ->
                                       builder.visit(
                                               //Bind all necessary attributes here                                                
                    .installOn(instrumentation);

有什么方法可以实现吗?我没有找到任何关于 ElementMatchers 的信息。

【问题讨论】:

  • 一个类定义了该类所有实例的属性和行为。这是 OOP 的基本原则(用类而不是原型来实现)。当类不是最终类时,您可以创建具有不同行为的子类,并将从 A 到 C 的引用替换为对该子类实例的引用。否则,不,您不能改变单个对象的行为。 Java 对象不是这样工作的。
  • 感谢遮阳篷,我认为这是事实。总的来说,这对我来说并没有那么糟糕。它只是让我弄清楚 ResettableClassFileTransformer 是如何工作的,以及为什么它在我的情况下不能按预期工作(所以我希望 ist 工作,认为它按设计工作)。我的问题更像是解决方案的捷径。

标签: java bytecode byte-buddy


【解决方案1】:

您可以像我们在 Mockito 中所做的那样模拟这一点,以在使用内联模拟制作器时识别实例 is a regular instance or a mock。一般来说,instrument是为了调整:

void m() {
  // some code
}

进入

void m() {
  if (MyFramework.isActive(this)) {
    // your code
  } else {
    // some code
  }
}

但这不适用于匹配器,但您需要在代码中实现。您不能将一个类重新转换为仅针对给定的一组实例进行调整。类的想法是定义作为该类的直接实例的任何对象的形状。

【讨论】:

    猜你喜欢
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-21
    • 1970-01-01
    • 1970-01-01
    • 2021-03-09
    相关资源
    最近更新 更多