ref()没有使用grails上的spring dsl获取嵌套映射值的bean配置

时间:2014-06-02 01:26:50

标签: spring grails groovy dsl

Grails 2.3.7 上,尝试使用resources.groovy中的bean引用设置嵌套地图值

   msgbean(Message){
      text = 'hello'
   }

   bean1(ConfigObj){
      prop = [ref('msgbean')]
   }

   bean2(ConfigObj){
      prop = [key: ref('msgbean')]
   }

   bean3(ConfigObj){
      prop = [key:[msg:ref('msgbean')]]
   }

bean1bean2正确连线,

  println '1 ' + bean.prop[0].text
  println '2 ' + bean2.prop['key'].text

...打印

1 hello
2 hello
但是,

bean3没有引用msgbean ...

println '3 ' + bean3.prop['key']['msg'].text

Error |
No such property: text

仔细观察,bean3.prop['key']['msg']最终不是Message,而是RuntimeBeanReference的实例,beanName=<msgbean>;所以我尝试在其上调用getSource(),返回null,这可能发生according到文档(对我来说不对)

为什么ref()不能用于嵌套地图?

备用:内联DSL配置

这样的事情也会很好;这可能吗?给了它一个镜头,返回一个关闭,当执行时,返回'你好';没有惊喜,但不是我想要的;需要Message实例。

bean3(ConfigObj){
      prop = [key:[msg:{Message -> {
                          text = 'hello'
                       }
               ]]
   }

2 个答案:

答案 0 :(得分:3)

为了在运行时自动解包RuntimeBeanReference,弹簧上下文中配置的Map需要为org.springframework.beans.factory.support.ManagedMap - spring DSL会自动转换包含RuntimeBeanReference值的任何地图进入一个ManagedMap,但它只在一个深度上执行此操作,它不会查看地图的地图等。

有点乱,但您可以将内部地图声称为顶级bean:

bean3Message(org.springframework.beans.factory.config.MapFactoryBean) {
   sourceMap = [msg:ref('msgbean')]
}

bean3(ConfigObj){
   prop = [key:ref('bean3Message')]
}

现在地图都包含第一级的运行时引用,因此两者都将被“正确管理”。

答案 1 :(得分:0)

另一种适合我的解决方案:

bean3(ConfigObj) {
    prop = [key : ref(bean3Message(org.springframework.beans.factory.config.MapFactoryBean) {
            sourceMap = [msg:ref('msgbean')]
    })]
}

它也很混乱,但您不必将地图定义分布在多个顶级bean中。

我已尝试使用list(使用带有sourceList属性的org.springframework.beans.factory.config.ListFactoryBean而不是sourceMap)。