使用 ByteBuddy 访问截获的 class 中的私有字段

Accessing private fields in an intercepted class, using ByteBuddy

如果我有 class,请说:

public class Foo {
    private String name;

    //...

    public void someMethod(Object someArg) {
    }
}

.. 我想使用 Java 代理拦截 'someMethod',所以我按照以下方式做了一些事情:

public static void premain(String args, Instrumentation inst) {

    new AgentBuilder.Default()
            .type(ElementMatchers.named("Foo"))
            .transform((builder, typeDescription, classLoader, module)
             -> builder.method(
                 ElementMatchers.named("someMethod"))
                 .intercept(MethodDelegation.to(Interceptor.class))
            )

            .installOn(inst);
}

public class Interceptor() {
    public static void intercept(
        @AllArguments Object[] args,
        @This Foo foo,
        @SuperCall Callable zuper) {

            if (foo.name.equals("BAR") //foo.name inaccessible here
               zuper();
            else {/*something else*/}
    }
}

如何在拦截方法中使用 ByteBuddy 来访问 class Foo 的 'name' 字段?

ByteBuddy 能否公开该私有变量供我检查(或者我猜是修改,但对于我的用例,只读就可以了)?

如果您只想读取一个值,可以使用 @FieldValue 注释:

public class Interceptor() {
  public static void intercept(
    @AllArguments Object[] args,
    @FieldValue("name") String name,
    @SuperCall Callable zuper) {
        if (name.equals("BAR"))
           zuper();
        else {/*something else*/}
  }
}

如果你想写一个值,你必须使用(并安装)@FieldAccessor