【问题标题】:Where invokeMethod in groovy is implemented?groovy中的invokeMethod在哪里实现?
【发布时间】:2014-03-08 15:35:10
【问题描述】:

我正在读一本书“Venkat Subramaniam 编写的 Groovy 2 编程”,在那本书的第 12 章 [使用 MOP 的拦截方法] 下,他给出了 “如果 Groovy 对象实现了 GroovyInterceptable 接口,那么它的调用方法()是 调用它的所有方法调用。”。我测试了这个及其工作。我的问题是,如果我在该类上实现 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;
}

}

【问题讨论】:

    标签: java groovy


    【解决方案1】:

    我不确定您在寻找什么,但也许这会有所帮助。在 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

    这有帮助吗?

    【讨论】:

    • 谢谢,是的,它有帮助
    【解决方案2】:

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

    【讨论】:

    • 感谢您的回答
    【解决方案3】:

    默认情况下,groovy 对象具有 GroovyObject 接口的实现,因此具有在该接口中定义的 invokeMethod 方法的实现。这可以解释为什么即使您没有在 Phone 类中实现 invokeMethod 方法,您的代码也能正常工作。

    【讨论】:

      猜你喜欢
      • 2010-12-18
      • 2012-04-24
      • 1970-01-01
      • 1970-01-01
      • 2019-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-13
      相关资源
      最近更新 更多