Groovy: делегировать метакласс для интерфейса? - PullRequest
5 голосов
/ 13 февраля 2009

Используя соглашение об именах пакетов Groovy, я могу перехватывать вызовы методов Groovy для метода Java следующим образом:

package groovy.runtime.metaclass.org.myGang.myPackage

class FooMetaClass extends groovy.lang.DelegatingMetaClass
{
    FooMetaClass(MetaClass delegate)
    {
        super(delegate);
    }

    public Object getProperty(Object a, String key)
    {
        return a.someMethod(key)
    }
}

Это прекрасно работает, если я действительно создаю объект класса Foo:

def myFoo = new Foo()
def fooProperty = myFoo.bar // metaclass invokes myFoo.someMethod("bar")

Однако что, если Foo является интерфейсом, и я хочу перехватывать вызовы методов для любой его реализации?

def myFoo = FooFactory.create()   // I don't know what class this will be
fooProperty = myFoo.bar

Есть ли способ достичь этого без наличия DelegatingMetaClass для каждой известной реализации интерфейса?

1 Ответ

4 голосов
/ 15 февраля 2009

Вы можете создать класс с именем "groovy.runtime.metaclass.CustomMetaClassCreationHandle" для глобальной обработки процесса создания метакласса.

Внутри этого класса вы можете переопределить этот метод:

protected MetaClass createNormalMetaClass(Class theClass, MetaClassRegistry registry) {
  // if theClass instanceof Foo, return your special metaclass
  // else return super.createNormalMetaClass(theClass, registry)
}
...