2009-11-19 24 views
5

'u kullanarak Groovy'de arabirimi uygulama Groovy, Java arabirimleriyle uğraşmak ve bunları uygulamak için bazı gerçekten düzgün dil özellikleri sunar, ancak sıkışmış gibi görünüyorum.Dinamik olarak invokeMethod

GroovyInterceptable.invokeMethod kullanarak Groovy sınıfında bir Arabirimi dinamik olarak uygulamak ve tüm arabirimdeki tüm yöntem çağrılarını durdurmak istiyorum. Kapatma çalışıyor dönen

public interface TestInterface 
{ 
    public void doBla(); 
    public String hello(String world); 
} 


import groovy.lang.GroovyInterceptable; 

class GormInterfaceDispatcher implements GroovyInterceptable 
{ 
    def invokeMethod(String name, args) { 
     System.out.println ("Beginning $name with $args") 
     def metaMethod = metaClass.getMetaMethod(name, args) 
     def result = null 
     if(!metaMethod) 
     { 
      // Do something cool here with the method call 

     } 
     else 
      result = metaMethod.invoke(this, args) 
     System.out.println ("Completed $name") 
     return result 
    } 

    TestInterface getFromClosure() 
    { 
     // This works, but how do I get the method name from here? 
     // I find that even more elegant than using invokeMethod 
     return { Object[] args -> System.out.println "An unknown method called with $args" }.asType(TestInterface.class) 
    } 


    TestInterface getThisAsInterface() 
    { 
     // I'm using asType because I won't know the interfaces 
     // This returns null 
     return this.asType(TestInterface.class) 
    } 

    public static void main(String[] args) 
    { 
     def gid = new GormInterfaceDispatcher() 
     TestInterface ti = gid.getFromClosure() 
     assert ti != null 
     ti.doBla() // Works 
     TestInterface ti2 = gid.getThisAsInterface() 
     assert ti2 != null // Assertion failed 
     ti2.doBla() 
    } 
} 

ama orada çağrılan yöntemin adını bulmak için bir yol çözemedim: İşte ben bugüne kadar ne çalıştığımız.

Bu referansın kendisinde bir Proxy oluşturmaya çalışarak (yöntem çağrıları invokeMethod çağırır) null değerini döndürür.

cevap

9

dinamik verilen arayüz temsil eden bir harita oluşturmak için Groovy Haritası zorlama özelliğini kullanabilirsiniz:

TestInterface getMapAsInterface() { 
    def map = [:] 

    TestInterface.class.methods.each() { method -> 
    map."$method.name" = { Object[] args-> 
     println "Called method ${method.name} with ${args}" 
    } 
    }  

    return map.asType(TestInterface.class) 
} 
+0

Çok teşekkürler, bir çekicilik gibi çalışır ve temiz görünüyor ve hala tüm üye değişkenleri ve yöntemleri erişebilirsiniz. – Daff

+0

Bu, aşırı yüklü yöntemlere sahip arayüzler için işe yaramıyor. –

0

Christoph yanıtını tamamlamak için, bu page belirttiği gibi, sizinle bir arabirim uygulayabilen bir kapatma. Örneğin:

def map = [doBla: { println 'Bla!'}, hello: {world -> "Hello $world".toString()}] as TestInterface 
map.hello 'Groovy' // returns 'Hello Groovy'