Grails:为什么这个服务类是空的?

Grails:为什么这个服务类是空的?,grails,groovy,Grails,Groovy,考虑到这种极其简化的设置格式: package net.myexample.plugin class MyExampleService { Map doMunge(Map m) { // do stuff to 'm' return m } } /****************************** BREAK: NEXT FILE ******************************/ package net.myexample.plugin

考虑到这种极其简化的设置格式:

package net.myexample.plugin

class MyExampleService {  
  Map doMunge(Map m) {
    // do stuff to 'm'
    return m
  }
}

/****************************** BREAK: NEXT FILE ******************************/

package net.myexample.plugin

class MyTagLib {
  static namespace = 'p'

  def myExampleService

  def tag = { attrs, body ->
    def m = doMungeAndFilter(attrs.remove('m'))

    out << g.render(template: '/template', plugin: 'my-example-plugin', model: m)
  }

  Map doMungeAndFilter(def m) {
    def mm = myExampleService.doMunge(m)
    // do stuff to 'm'
    return mm
  }
}

/****************************** BREAK: NEXT FILE ******************************/

package net.myexample.app

import net.myexample.plugin.MyExampleService

class MyExampleService extends net.myexample.plugin.MyExampleService {
  def doMunge(def m) {
    def mm = super.doMunge(m)
    // do more stuff to 'mm'
    return mm
  }
}

/****************************** BREAK: NEXT FILE ******************************/

package net.myexample.app

import net.myexample.plugin.MyTagLib

class MyTagLib extends net.myexample.plugin.MyTagLib {
  static namespace = 'a'

  def myExampleService

  def tag = { attrs, body ->
    def m = doMungeAndFilter(attrs.remove('m'))

    out << g.render(template: '/template', plugin: 'my-example-plugin', model: m)
  }

  Map doMungeAndFilter(def m) {
    def mm = super.doMungeAndFilter(m)
   // do more stuff to 'mm'
    return mm
  } 
}

/**
 * But we get an exception that cites that it cannot call 'doMunge' on a null
 * object -- which could only be 'myExampleService'
 */
package net.myexample.plugin
类MyExampleService{
多蒙格地图(m地图){
//对我做点什么
返回m
}
}
/******************************中断:下一个文件******************************/
包net.myexample.plugin
类MyTagLib{
静态命名空间='p'
def myExampleService
def标记={attrs,body->
def m=doMungeAndFilter(属性删除('m'))
出来
def m=doMungeAndFilter(属性删除('m'))

out这只是一个简单的猜测,但是您的taglib类文件是位于/grails app/taglib下,还是位于/src目录中?我注意到我无法让服务注入(至少是自动地)进入位于/grails app文件夹外的类。

从子类taglib中删除
def myExampleService
。Groovy中的属性编译为私有字段加上公共getter和setter,因此在超类taglib中隐式

private Object myExampleService;

public void setMyExampleService(Object svc) {
  this.myExampleService = svc;
}
// getter similar
在子类中再次声明
myExampleService
时,子类将获得自己的私有字段(同名)并且setter被重写,将提供的值存储在这个子类字段中,而不是超类字段中。Spring调用setter来注入服务,因此最终结果是超类private
myExampleService
从未被设置,因此在尝试调用
myExampleService.doMunge
i时出现空指针异常n超类


子类可以通过继承的getter和setter访问超类属性,因此不需要重新声明它。

如果这是Grails错误,我不会感到惊讶。我知道过去从流内部调用服务或其他Grails类将无法实例化服务并将服务注入该类。这可能是一个similar问题。Grails很棒,也很有用,但还远远不够完美。@BillJames-有趣,我不知道这一点。听起来我会更深入地挖掘,看看是否能找到更多。是的——它在Grails应用程序/taglib中。