この非常に単純化されたセットアップの表現を考えると、次のようになります。
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 のメソッドがそのスーパークラス (プラグインの taglib) を呼び出し、そのスーパークラスがサービスのメソッドを呼び出すと、なぜサービスが表示されるのでしょうか?
私が思いつく最良の理論は、サービスは実際にはアプリの taglib クラスでインスタンス化されていないということdef
です。すべてのロジックをサービス クラスのメソッドから taglib のメソッドに移動すると、期待どおりに動作するため、これが当てはまると思います。
(全体像を描くために:MyExampleService.doMunge
は他の場所で呼び出されますが、その後のフィルタリング ( MyTagLib.doMungeAndFilter
) は taglib にのみ必要です。)
または、別のサービス クラスに移動doMungeAndFilter
して、プラグインでベース バージョンを作成し、それをアプリで拡張すると、問題なく動作します。そのようなtaglibをサポートするためだけに別のサービスクラスを作成するのは肥大化しているように感じますが、これは受け入れられる結論だと思います.
考え?チップ?明らかな誤りや脱落?