Мое понимание - то, что существует два очевидных места в приложении Grails, где можно сделать метапрограммирование:
init
закрытие Bootstrap.groovy
doWithDynamicMethods
закрытие плагинаМетапрограммирование, к которому я обращаюсь здесь, должно быть видимо всюду по приложению, типичные примеры включают добавление (или замена) методы сторонних классов.
String.metaClass.myCustomMethod = { /* implementation omitted */ }
Недостаток (1), то, что метапрограммирование не будет применено, когда приложение будет динамично перезагружено. Недостаток (2) - то, что я должен создать и поддержать весь плагин только ради небольшого метапрограммирования.
Существует ли лучшее место, чтобы сделать этот вид метапрограммирования?
Предложение следующего Ted's ниже, я добавил следующий класс к src/groovy
package groovy.runtime.metaclass.java.lang
/**
* Adds custom methods to the String class
*/
class StringMetaClass extends DelegatingMetaClass {
StringMetaClass(MetaClass meta) {
super(meta)
}
Object invokeMethod(Object object, String method, Object[] arguments) {
if (method == 'hasGroovy') {
object ==~ /.*[Gg]roovy.*/
} else {
super.invokeMethod object, method, arguments
}
}
}
Затем перезапущенный приложение и выполнил следующий код в консоли Grails:
assert 'mrhaki loves Groovy'.hasGroovy()
Я получил следующее исключение
groovy.lang.MissingMethodException: No signature of method:
java.lang.String.hasGroovy() is applicable for argument types: () values: []
Я делаю что-то не так или являюсь там причиной, это не работает в приложении Grails?
Ознакомьтесь с Делегирующим метаклассом , это part of groovy и заставляет ваш метакласс изменять часть метакласса, которая используется в каждом экземпляре этого класса с самого начала. Он работает по простому соглашению и даже работает вне грааля.
В зависимости от вашего варианта использования Преобразования Groovy AST являются третьим вариантом. Преобразование AST - это модификации байт-кода во время компиляции. Они доступны начиная с Groovy 1.6 и были значительно улучшены в Groovy 1.7. Esp. ASTBuilder - очень элегантный способ.
Имейте в виду, что использование AST в Grails может потребовать некоторых изменений в сборке. Классы, выполняющие AST, должны быть скомпилированы до классов, которые подчиняются AST. Это можно легко сделать, подключившись к событию «CompileStart» в scripts / _Events.groovy и предварительно скомпилировав преобразование.