2009-10-23 94 views
0

我試圖攔截所有對Groovy類屬性的調用。由於這沒有按預期工作,我創建了以下示例:攔截對屬性的調用

class TestClass { 
    def getProperty(String key) { 
     println "getting property: " + key 
    } 

    def invokeMethod(String method, args) { 
     println "invoking method: " + method 
    } 

    def getFoo() { 
     return 1 
    } 
} 
tc.foo  // 1 
tc.getFoo() // 2 

1)做了正確的事情,即調用getProperty。但是,2)工作(即返回1),但getProperty和invokeMethod都不會被調用。

有沒有辦法攔截getfoo()調用?

斯特凡

回答

0

我幾個月前寫了一篇文章。你可以閱讀它here

試試這個代碼:

TestClass.metaClass.invokeMethod = { 
    def metaMethod = delegate.metaClass.getMetaMethod(method,args) 
    println "executing $method with args $args on $delegate" 
    return metaMethod.invoke(delegate,args) 
} 
0

我不得不修改代碼在前面的回答有點讓我想你想:

TestClass.metaClass.invokeMethod = {method, args -> 
    def metaMethod = TestClass.metaClass.getMetaMethod(method,args) 
    println "executing $method with args $args on $delegate" 
    metaMethod.invoke(delegate,args) // could result in NPE 
} 

然後執行

tc.foo 
tc.getFoo() 

結果於:

getting property: foo        // println output 
null            // getProperty return is null 
executing getFoo with args [] on [email protected] // invokeMethod output 
1             // metaMethod invocation 
0

問題在於這裏使用了兩種不同的路徑來處理請求。對於提問屬性,在進入元類之前調用​​getProperty方法 - 如果覆蓋getProperty,則必須實際執行元類調用。在invokeMethod的情況下,在之後通常詢問元類已被詢問。由於元類將響應你對getFoo()的要求,所以invokeMethod根本不會被詢問。如果讓類實現GroovyInterceptable,那麼首先會詢問invokeMethod,就像getProperty一樣。這也解釋了爲什麼使用元類的方法可行。