1

可以将基于闭包的配置实现为地图地图吗?

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.目的)

我对此感到有些困惑,我认为这是不可能的,而且我不确定如何动态地处理基于闭包的约定。

4

2 回答 2

3

您的代码的一个问题可能是配置节点结构看起来完全正常,但实际上并非如此。即有些节点是Map实例,但不是ConfigObject实例。

在大多数情况下,这可能无关紧要,但在您的情况下,第 3 方插件似乎因一些丑陋且难以理解的异常而失败。

我无法重现您的问题,因此我无法确定这是否是您遇到的真正问题,也无法确定建议的解决方案是否能解决您的问题。尽管如此,我的第一次尝试是修复类型,以便配置树中的所有节点都是 type ConfigObject。像这样的东西:

def poolProps = [timeout: 5000] as ConfigObject // convert type to ConfigObject
grails.acme.host = 'localhost'
grails.acme << [ poolSettings : poolProps ]

请注意,如果您创建的地图(在本例中为 poolProps)包含嵌套的地图元素,您也必须转换这些元素。

于 2014-09-28T11:11:08.043 回答
1

Yes it is possible, actually

grails {
   acme {
      host = 'localhost'
      poolSettings {
         timeout = 5000
      }
   }
}

is the same as:

grails.acme.host = 'localhost'
grails.acme.poolSettings.timeout = 5000

the closures are just syntactic sugar. You can even combine both types:

grails.acme {
   host = 'localhost'
   poolSettings.timeout = 5000
}
于 2014-09-28T05:29:14.030 回答