Как создать ConfigObject, используя только вложенные карты в Grails?
Можно ли реализовать закрывающий конфиг в виде карты карт?
grails {
acme {
host = 'localhost'
poolSettings {
timeout = 5000
}
}
}
Приведенный выше конфиг является соглашением для плагина Grails. Мы осуществляем миграцию, и из-за устаревших ограничений нам необходимо динамически создавать конфигурацию, чтобы исключить влияние на устаревший код.
Я начал с простого конфига:
grails.acme = [host:'localhost']
Это прекрасно работает с плагином при запуске, поэтому я добавил вложенную карту:
grails.acme = [host:'localhost']
def poolProps = //do some work to get pool settings
grails.acme << [poolSettings:poolProps]
При запуске я довольно печатаю grails.acme
:
{
"host": "locahost",
"poolSettings": {
"timeout": 5000
}
}
Это выглядит нормально, но вскоре после плагина acme происходит сбой со следующей ошибкой:
2014-09-27 23: 27: 07,460 [localhost-startStop-1] ERROR context.GrailsContextLoader - Ошибка при инициализации приложения: нет подписи метода: AcmePlugin$_closure2_closure5_closure9 .doCall() применим для типов аргументов: (grails.spring.BeanBuilder) значения: [grails.spring.BeanBuilder@7b067fd7] Возможные решения: doCall(java.lang.Object, java.lang.Object), call(), call([Ljava.lang.Object;), call(java.lang.Object), call(java.lang.Object, java.lang.Object), findAll() Сообщение: нет подписи метода: AcmeGrailsPlugin$_closure2_closure5_closure9.doCall() применимо для типов аргументов: (grails.spring.BeanBuilder) значения: [grails.spring.BeanBuilder@7b067 fd7] Возможные решения: doCall (java.lang.Object, java.lang.Object), call (), call ([Ljava.lang.Object;), call (java.lang)..Object), вызов (java.lang.Object, java.lang.Object)
Я немного озадачен этим, я предполагаю, что это невозможно, и я не уверен, как даже приблизиться к соглашению на основе замыканий динамически.
2 ответа
Одна проблема с вашим кодом может заключаться в том, что структура узла конфигурации выглядит отлично, но на самом деле это не так. Т.е. что некоторые узлы Map
случаи, но не ConfigObject
экземпляров.
В большинстве случаев это, вероятно, не будет иметь значения, но в вашем случае кажется, что сторонний плагин дает сбой с некоторым уродливым и непонятным исключением.
Я не могу воссоздать вашу проблему, поэтому не могу с уверенностью сказать, является ли это реальной проблемой, с которой вы столкнулись, или предлагаемое решение решило вашу проблему. Тем не менее, моей первой попыткой было бы исправить типы так, чтобы все узлы в дереве конфигурации имели тип ConfigObject
, Что-то вроде этого:
def poolProps = [timeout: 5000] as ConfigObject // convert type to ConfigObject
grails.acme.host = 'localhost'
grails.acme << [ poolSettings : poolProps ]
Обратите внимание, что если создаваемые вами карты (в данном случае poolProps) содержат вложенные элементы карты, вам также придется конвертировать их.
Да это возможно, на самом деле
grails {
acme {
host = 'localhost'
poolSettings {
timeout = 5000
}
}
}
такой же как:
grails.acme.host = 'localhost'
grails.acme.poolSettings.timeout = 5000
замыкания - это просто синтаксический сахар. Вы даже можете комбинировать оба типа:
grails.acme {
host = 'localhost'
poolSettings.timeout = 5000
}