这篇博客文章介绍了将Grails中的依赖项注入与继承结合使用时应注意的一个小陷阱。
我认为最好用一段示例代码来解释该问题。 因此,让我们看一下Grails控制器的以下两个定义。
class FooController {
TestService testService
def foo() {
// do something with testService
}
}
class BarController extends FooController {
TestService testService
def bar() {
// do something with testService
}
}
两个控制器看起来几乎相同。 唯一的区别是BarController扩展了FooController。 现在假设我们有一个BarController的实例,我们想在其上调用方法bar()和foo()。 猜猜会发生什么?
bar()的调用工作正常,而foo()的调用则抛出NullPointerException,因为testService为null。
testService是一个标准的Groovy属性 。 这意味着testService字段将变为私有,并且将为两个控制器生成getter / setter方法。 BarController的getter / setter覆盖FooController的getter / setter。 因此,无论何时使用setTestService()注入依赖项,只有BarController都会检索TestService实例。 对于Grails控制器,这没什么特别的,它对于服务和其他Groovy类的工作原理相同。
解决方案很简单:从BarController删除testService依赖项。 每当在BarController中访问testService时,它将使用FooController的适当的吸气剂,并且一切正常。
在这个简单的示例中,问题非常明显,可以轻松解决。 但是,如果您的类变大,则调试起来可能会有些棘手。 假设您有一个带有多个子类的基类。 每当您要向基类添加新的依赖项时,都必须检查所有子类。 如果子类之一已经定义了相同的依赖项,则必须将其删除,否则它将在您的基类中不可用。
翻译自: https://www.javacodegeeks.com/2014/04/the-grails-depedency-injection-inheritance-pitfall.html