重新定义class,拦截getter方法,以便修改getterreturn值
Redefine class, intercepting getter method in order to modify the getter return value
我是这样定义我的建议的:
public class MyInterceptor {
@Advice.OnMethodExit
public static void intercept(@Advice.Return String value) {
// do my changes
}
}
这是我要重新定义的class:
public class MyClass {
private String field;
public MyClass() {
}
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
}
我的 JUnit 测试:
@Test
public void buddytest() throws Exception {
new ByteBuddy()
.redefine(MyClass.class)
.method(named("getField"))
.intercept(to(MyInterceptor.class))
.make()
.load(getClass().getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
MyClass myClass = new MyClass();
myClass.setField("xxx");
String field = myClass.getField();
}
但是当我 运行 我的测试时, MyInterceptor.intercept() 方法没有被调用并且抛出了这个异常:
java.lang.IllegalStateException: Cannot call super (or default) method for public java.lang.String package.MyClass.getField()
我做错了什么?提前谢谢你。
您正在使用 Advice
作为拦截器而不是装饰器。这样,Byte Buddy 实现了该方法,默认情况下作为超级方法调用在您的情况下是不可能的。这种模式在创建子类时很有意义。您可以通过以下方式创建装饰:
new ByteBuddy()
.redefine(MyClass.class)
.visit(Advice.to(MyInterceptor.class).on(named("getField")))
我是这样定义我的建议的:
public class MyInterceptor {
@Advice.OnMethodExit
public static void intercept(@Advice.Return String value) {
// do my changes
}
}
这是我要重新定义的class:
public class MyClass {
private String field;
public MyClass() {
}
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
}
我的 JUnit 测试:
@Test
public void buddytest() throws Exception {
new ByteBuddy()
.redefine(MyClass.class)
.method(named("getField"))
.intercept(to(MyInterceptor.class))
.make()
.load(getClass().getClassLoader(), ClassReloadingStrategy.fromInstalledAgent());
MyClass myClass = new MyClass();
myClass.setField("xxx");
String field = myClass.getField();
}
但是当我 运行 我的测试时, MyInterceptor.intercept() 方法没有被调用并且抛出了这个异常:
java.lang.IllegalStateException: Cannot call super (or default) method for public java.lang.String package.MyClass.getField()
我做错了什么?提前谢谢你。
您正在使用 Advice
作为拦截器而不是装饰器。这样,Byte Buddy 实现了该方法,默认情况下作为超级方法调用在您的情况下是不可能的。这种模式在创建子类时很有意义。您可以通过以下方式创建装饰:
new ByteBuddy()
.redefine(MyClass.class)
.visit(Advice.to(MyInterceptor.class).on(named("getField")))