【问题标题】:ref() not getting bean config for nested map value using spring dsl on grailsref()没有使用grails上的spring dsl获取嵌套映射值的bean配置
【发布时间】:2014-06-02 01:26:50
【问题描述】:

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 配置

这样的东西也不错;这可能吗?试一试,返回一个闭包,执行时返回 'hello';这并不奇怪,但不是我想要的;需要 Message 实例。

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

【问题讨论】:

    标签: spring grails groovy dsl


    【解决方案1】:

    为了让RuntimeBeanReferences 在运行时自动解包,spring 上下文中配置的 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')]
    }
    

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

    【讨论】:

    • Ian,如果MapFactoryBean 支持一层深度,那么它们比支持他的简单地图有什么好处?我可以使用内联配置分配地图值吗? (见我的更新)。
    • @raffian 这与 MapFactoryBean 无关 - DSL 将转换为分配给 bean 属性并包含至少一个 RuntimeBeanReference 的 ManagedMap any 映射作为一个值。这不是我使用MapFactoryBean 与此处相关的事实,而是我正在定义一个具有属性(sourceMapprop)的命名bean(bean3Messagebean3) ),其值为 Map。
    【解决方案2】:

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

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

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

    我已经用列表尝试过这个(使用带有属性 sourceList 而不是 sourceMap 的 org.springframework.beans.factory.config.ListFactoryBean)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-24
      • 1970-01-01
      • 2011-12-01
      • 1970-01-01
      • 2015-01-31
      • 2016-04-24
      • 2013-12-05
      • 2020-08-24
      相关资源
      最近更新 更多