跟大家分享Groovy中Meta-Object-Protocol(MOP)及Meta Classes的觀念,Run time時程Groovy有作哪些事以及可以動態新增修改什麼屬性或是方法,內容比較多會拆成大概三天來分享吧~
基本上gvoovy是在JVM上run的語言,所以不管怎麼走最後一定要產生bytecode,才能在JVM上執行,不管是直接groovy xxx.groovy或是pre-complie,終究會轉成bytecode在JVM上執行,
所以如果要在run time變更method的實作或是添加屬性(property),如上一篇分享之
GroovyBean及Expanso http://ithelp.ithome.com.tw/question/10130915
則意謂runtime時必須要有一個機制可以改寫或是產生bytecode,這就是所謂的Meta-Object-Protocol(MOP),其中meta的概念或是概念就是自動產生一個object的source code, 相關method等,或是稱作metaprogramming,這部份概念比較抽象,等一下會舉例。
MOP就是在探討Groovy class與MetaClass的連結與應用,首先先介紹GroovyObject這個interfce
所有Groovy class都會實作GroovyObject interface
public interface GroovyObject {
public Object invokeMethod(String name, Object args);
public Object getProperty(String property);
public void setProperty(String property, Object newValue);
public MetaClass getMetaClass();
public void setMetaClass(MetaClass metaClass);
從程式碼可以看出至少兩件事
GroovyBean中getter/setter其實已經在GroovyObject定義了getProperty/setProperty
GroovyObject是與MetaClass有所連結的,而在MetaClass預設實作以下方法
Object invokeMethod(Object obj, String methodName, Object args)
Object invokeMethod(Object obj, String methodName, Object[] args)
Object invokeStaticMethod(Object obj, String methodName, Object[] args)
Object invokeConstructor(Object[] args)
從最後一行也就是告訴你為何我們在GroovyBean不需要特別在寫constructor,因為在其對應的MetaClass已經有預設實作,另外其他的方法也是透過InvokeMethod觸發,當然也可以override,如以下例子
對照
這個例子是override invokeMethod方法,把前一篇的Expando中MOP作的事情寫在原class裡
以下是個人猜測,可想而知metaclass在Groovy的真實程式中,一定是非常多的,故為有效管理與搜尋,Groovy引入MetaClassRegistry,所有的metaclass存放於MetaClassRegistry管理,MetaClassResgistry是唯一的,意味採用Singleton實作,示意圖如下
由以上所述所有的Groovy class行為如Call一個方法皆會引動MOP機制,示意圖如下:
Groovy與java如何互相相輔相成就需要額外的學習囉,Manning有出一本書:Make Your Java Groovy,有時間再跟大家分享囉,畢竟我也是邊看邊學^^
由以上看來metaclass似乎是有點java Reflection機制的fu,不過提供更彈性的應用,我想Expando就是一個例子,而之後也會介紹Groovy method的interceptor,類似或是就是Spring的AOP(Aspect-Oriented Programming)
Note: 以上圖片除了GroovyConsole之外,版權都是來自於原出版社