在实现groovy中的invokeMethod的地方?

时间:2014-03-08 15:35:11

标签: java groovy

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

}

3 个答案:

答案 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;
        }
    }
}

请参阅the source code here

这有帮助吗?

答案 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方法,你的代码也能正常工作。