我正在阅读一本书“Venkat Subramaniam编程Groovy 2”,在第12章[拦截方法使用MOP]下的那本书中,他给出了“如果Groovy对象实现了GroovyInterceptable接口,那么它invokeMethod()是 调用了它的所有方法调用。“。我测试了这个和它的工作。我的问题是,如果我在该类上实现invokeMethod(),那么它将被调用,否则调用默认的invokeMethod,但默认情况下invokeMethod()是在我的类中没有实现GroovyInterceptable接口,那么这个概念是如何工作的。
实现了GroovyInterceptable接口的类
class InterceptingMethodsUsingGroovyInterceptableExample {
static void main(String... args){
Phone phone = new Phone()
phone.mobileNumber = 9755055420
phone.mobileType = "Android"
println phone.save()
Phone phone2 = new Phone()
phone2.mobileNumber = 9755055420
//phone2.mobileType = "Android"
println phone2.save()
Phone phone3 = new Phone()
phone3.mobileNumber = 9755055420
println phone3.isValid()
}
}
class Phone implements GroovyInterceptable {
String mobileType;
Long mobileNumber
def isValid(){
def returnValue = false
if ((mobileType)&& (mobileNumber?.toString()?.length() == 10) )
returnValue = true
returnValue
}
def save(){
return "Saved"
}
}
Output :
Saved
Saved
false
JAD反编译电话代码:
public class Phone implements GroovyInterceptable{
private String mobileType;
private Long mobileNumber;
public Phone()
{
Phone this;
CallSite[] arrayOfCallSite = $getCallSiteArray();
MetaClass localMetaClass = $getStaticMetaClass();
this.metaClass = localMetaClass;
}
public Object isValid()
{
CallSite[] arrayOfCallSite = $getCallSiteArray();Object returnValue = Boolean.valueOf(false);
boolean bool1;
boolean bool2;
if ((!BytecodeInterface8.isOrigInt()) || (!BytecodeInterface8.isOrigZ()) || (__$stMC) || (BytecodeInterface8.disabledStandardMetaClass()))
{
if (((DefaultTypeTransformation.booleanUnbox(this.mobileType)) && (ScriptBytecodeAdapter.compareEqual(arrayOfCallSite[0].callSafe(arrayOfCallSite[1].callSafe(this.mobileNumber)), Integer.valueOf(10))) ? 1 : 0) != 0)
{
bool1 = true;returnValue = Boolean.valueOf(bool1);
}
}
else if (((DefaultTypeTransformation.booleanUnbox(this.mobileType)) && (ScriptBytecodeAdapter.compareEqual(arrayOfCallSite[2].callSafe(arrayOfCallSite[3].callSafe(this.mobileNumber)), Integer.valueOf(10))) ? 1 : 0) != 0)
{
bool2 = true;returnValue = Boolean.valueOf(bool2);
}
return returnValue;return null;
}
public Object save()
{
CallSite[] arrayOfCallSite = $getCallSiteArray();return "Saved";return null;
}
static {}
public String getMobileType()
{
return this.mobileType;
}
public void setMobileType(String paramString)
{
this.mobileType = paramString;
}
public Long getMobileNumber()
{
return this.mobileNumber;
}
public void setMobileNumber(Long paramLong)
{
this.mobileNumber = paramLong;
}
}
答案 0 :(得分:3)
我不确定你在寻找什么,但也许这会有所帮助。在Groovy运行时中有一些地方我们在方法调用时询问一个对象,看看它是否实现了GroovyInterceptable,然后相应地做出响应。例如,在InvokerHelper中有如下代码:
static Object invokePogoMethod(Object object, String methodName, Object arguments) {
GroovyObject groovy = (GroovyObject) object;
boolean intercepting = groovy instanceof GroovyInterceptable;
try {
// if it's a pure interceptable object (even intercepting toString(), clone(), ...)
if (intercepting) {
return groovy.invokeMethod(methodName, asUnwrappedArray(arguments));
}
//else try a statically typed method or a GDK method
return groovy.getMetaClass().invokeMethod(object, methodName, asArray(arguments));
} catch (MissingMethodException e) {
if (e instanceof MissingMethodExecutionFailed) {
throw (MissingMethodException) e.getCause();
} else if (!intercepting && e.getMethod().equals(methodName) && object.getClass() == e.getType()) {
// in case there's nothing else, invoke the object's own invokeMethod()
return groovy.invokeMethod(methodName, asUnwrappedArray(arguments));
} else {
throw e;
}
}
}
这有帮助吗?
答案 1 :(得分:1)
如果您的类实现了GroovyInterceptable,那么无论何时从类扩展的类调用方法,都将调用invokeMethod。
class MyInterceptor implements GroovyInterceptable {
def invokeMethod(String name, Object args) {
println "Called everytime a method is invoked."
}
}
class Example extends MyInterceptor {
void someMethod() {
print "Prints something"
}
}
答案 2 :(得分:1)
默认情况下,groovy对象具有GroovyObject接口的实现,因此是该接口中定义的invokeMethod方法的实现。这可以解释为什么即使你没有在Phone类中实现invokeMethod方法,你的代码也能正常工作。