使用 Byte Buddy 的简单前后方法拦截器
Simple After And Before Method Interceptor With Byte Buddy
在撰写本文时,在 Byte Buddy tutorial 中,一切都得到了解释,但没有简单的前后方法拦截器,正如我在下面解释的那样,我是不是遗漏了什么,或者教程很复杂。 (参见 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
即使没有方法委托,您也可以实现这样的机制,如下所示:
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 都被覆盖以首先调用其超级方法,然后以 true
作为参数调用 setDirty
方法。然而,评论中的链接示例也应该有效。
拦截器可能如下所示(假定已实现某些接口 Dirtiable
):
public class Interceptor {
public static void getter(@SuperCall Runnable zuper, @This Dirtiable self) {
zuper.run();
self.setDirty(true);
}
}
这假设检测的超级 class 实现了 Dirtiable
接口,这可以使用 .implement(Dirtiable.class)
完成,其中可以使用 [=17= 实现该方法来设置字段] 实施。
在撰写本文时,在 Byte Buddy tutorial 中,一切都得到了解释,但没有简单的前后方法拦截器,正如我在下面解释的那样,我是不是遗漏了什么,或者教程很复杂。 (参见 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
即使没有方法委托,您也可以实现这样的机制,如下所示:
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 都被覆盖以首先调用其超级方法,然后以 true
作为参数调用 setDirty
方法。然而,评论中的链接示例也应该有效。
拦截器可能如下所示(假定已实现某些接口 Dirtiable
):
public class Interceptor {
public static void getter(@SuperCall Runnable zuper, @This Dirtiable self) {
zuper.run();
self.setDirty(true);
}
}
这假设检测的超级 class 实现了 Dirtiable
接口,这可以使用 .implement(Dirtiable.class)
完成,其中可以使用 [=17= 实现该方法来设置字段] 实施。