Runtime MetaProgramming
MOP - Meta Object Protocol, набор правил, как обрабатывается системой реального времени Groovy вызов в метод объекта и как контролируется промежуточный слой в объектах.Когда выполняется груви программа, "интерпритатор" может столнуться с тремя типами объекта, который пришел на выполнение, это:
- POJO - обычный объект Java, класс которого может быть написан на Java или любом другом языке для JVM
- POGO - объект Groovy, класс которого написан на Groovy. Он расширяет java.lang.Object и реализует groovy.lang.GroovyObject по умолчанию.
- Groovy Interceptor - объект Groovy, который реализует groovy.lang.GroovyInterceptable, этот интерфейс просто расширяет GroovyObject, не привнося никаких дополнительных деклараций, он просто говорит "интерпретатору", что все вызываемые методы должны дергать метод GroovyObject:: Object invokeMethod(String name, Object args), таким образом все вызовы перехватываются и проходят через прокси-метод класса, который мы объявили.
Содержимое GroovyObject:
package groovy.lang;
public interface GroovyObject {
Object invokeMethod(String name, Object args);
Object getProperty(String propertyName);
void setProperty(String propertyName, Object newValue);
MetaClass getMetaClass();
void setMetaClass(MetaClass metaClass);
}
И в зависимости от типа объекта, с которым мы имеем дело, вызов его метода может пройти по следующим цепочкам:
Обращение к реальному полю будет выглядеть так:
...
void setProperty(String name, Object value) {
this.@"$name" = value;
}
MetaClass
Любой класс в груви имеет ассоциированный с ним метакласс, который содержит все поля и методы, класса, который он поддерживает. И динамическая природа языка выражается в том, что мы во время выполнения можем в этот метакласс добавить дополнительные поля и методы, и таким образом обеспечить класс, поддерживаемый эти мета, новыми элементами в режиме реального времени.
Categories
Иногда бывает необходимость расширить какой-то GVM класс на участок кода(определенный момент выполнения), но не хотелось бы через metaClass портить класс и потом чистить его после работы (учитывая то, что может быть параллельное выполнение). Для эго и придумали оператор use и спецификацию категорий.
class StringCategory {
static String shout(String str) {
str.toUpperCase()
}
}
use(StringCategory) {
println "Hello, World!".shout()
}
GVM имеет уже ряд очень полезных категорий, которыми мы можем свободно пользоваться. Среди них и groovy.time.TimeCategory.
Compile Time MetaProgramming
Достигается с помощью аннотаций, который помогают не писать, а генерить по аннотации рутинный код, а также отключать например MOP режим например.


Комментариев нет:
Отправить комментарий