在撰写本文时Byte Buddy tutorial中,所有内容都有解释,但是我之前解释过一个简单的after和before方法拦截器,我错过了什么或教程很复杂。 (请参阅LoggerInterceptor示例给出方法但不是对象,ChangingLoggerInterceptor示例给出对象但不调用方法)
我想要实现的是在执行setter方法之后调用对象的方法。如何编写拦截器并在Java 6中使用它?
public class DirtyClass{
private String _sField;
private boolean _bDirty;
public void setField(String sField) {
_sField = sField;
//setDirty(true); to be appended after proxying
}
public String getField() {
return _sField;
}
public void setDirty(boolean bDirty){
_bDirty = bDirty;
}
public boolean isDirty(){
return _bDirty;
}
}
DirtyClass d = new ByteBuddy().subclass(DirtyClass.class)...???
d.setField("dirty now");
System.out.println(d.isDirty()); //Expecting true
答案 0 :(得分:7)
即使没有方法委派,您也可以实现这样的机制,如下所示:
DirtyClass d = new ByteBuddy()
.subclass(DirtyClass.class)
.method(isSetter().and(not(named("setDirty"))))
.intercept(SuperMethodCall.INSTANCE.andThen(
MethodCall.invoke(DirtyClass.class.getMethod("setDirty", boolean.class))
.with(true)
)).make()
.load(DirtyClass.class.getClassLoader())
.getLoaded()
.newInstance();
这样,每个setter都被重写,首先调用其super方法,然后以setDirty
为参数调用true
方法。但是,评论中的链接示例也应该有效。
拦截器可能如下所示(假设已实现某些接口Dirtiable
):
public class Interceptor {
public static void getter(@SuperCall Runnable zuper, @This Diriable self) {
zuper.run();
self.setDirty(true);
}
}
这假设已检测的超类实现了Dirtiable
接口,可以使用.implement(Dirtiable.class)
来完成,其中可以使用FieldAccessor
实现来设置字段。