鉴于设置的这种非常简化的再现:
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'
*/
null
当应用程序的标记库上的方法调用其超类(插件上的标记库)时,为什么服务会出现,而后者又调用服务上的方法?
我能想到的最好的理论是该服务实际上并没有在应用程序的 taglib 类中实例化,因为除了def
. 我认为是这种情况,因为如果我将所有逻辑从服务类的方法移到 taglib 的方法中,它就会按预期工作。
(为了画全图:MyExampleService.doMunge
在其他地方调用,而后面的过滤(in MyTagLib.doMungeAndFilter
)只有taglib需要。)
或者:如果我doMungeAndFilter
进入另一个服务类,在插件中创建基本版本并在应用程序中扩展它,那效果很好。我认为这是一个可以接受的结论,尽管创建另一个服务类只是为了支持这样的 taglib 感觉有点臃肿。
想法?尖端?明显的错误或遗漏?