Насколько я понимаю, в приложении Grails есть два очевидных места, где можно заниматься метапрограммированием:
-
init
закрытие Bootstrap.groovy
-
doWithDynamicMethods
закрытие плагина
Мета-программирование, о котором я здесь говорю, должно быть видно во всем приложении, типичные примеры включают добавление (или замену) методов сторонних классов.
String.metaClass.myCustomMethod = { /* implementation omitted */ }
Недостатком (1) является то, что метапрограммирование не будет применяться, когда приложение динамически перезагружается. Недостаток (2) заключается в том, что мне нужно создать и поддерживать весь плагин только ради небольшого метапрограммирования.
Есть ли лучшее место для такого рода метапрограммирования?
Обновление
Следуя предложенному Тедом ниже, я добавил следующий класс к 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?