使用 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
。
如果我有 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
。