Java groovy中的invokeMethod在哪里实现?

Java groovy中的invokeMethod在哪里实现?,java,groovy,Java,Groovy,我正在读一本书“Venkat Subramaniam编写的Groovy 2编程”,在该书的第12章[使用MOP拦截方法]中,他指出“如果Groovy对象实现GroovyInterceptable接口,那么它的invokeMethod()是 为其所有方法调用而调用。“。我测试了这个和它的工作。这里我的问题是,如果我在该类上实现invokeMethod(),那么它将被调用,否则会调用默认的invokeMethod,但默认情况下,invokeMethod()不在实现GroovyInterceptabl

我正在读一本书“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;
}

}

我不太确定您在找什么,但这可能会有所帮助。在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;
        }
    }
}


这有帮助吗?

如果您的类实现了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"
    }
}

默认情况下,groovy对象具有GroovyObject接口的实现,因此具有在该接口中定义的invokeMethod方法的实现。这就解释了为什么即使您没有在Phone类中实现invokeMethod方法,代码仍然有效。

谢谢您的回答谢谢,是的,它很有帮助