如何将类似服务的组件注入Grails域对象?

如何将类似服务的组件注入Grails域对象?,grails,dependency-injection,grails-domain-class,Grails,Dependency Injection,Grails Domain Class,我以前从未使用过Grails服务,但根据我的Web搜索,它们可以被注入到域对象中。因此,如果我有以下域类(假设BookService是在某处定义的) 当我使用,def Book=new Book()实例化Book对象时,应该设置Book.bookService 如果是这样,如果我想注入外部服务(或类似服务的组件),该怎么办?例如,如果有一个ISBNAPI客户机可用,我能期望grails以同样的方式注入它吗?例如,假设客户机是IsbnApi,我如何像其他服务一样自动注入?下面的代码行吗 class

我以前从未使用过Grails服务,但根据我的Web搜索,它们可以被注入到域对象中。因此,如果我有以下域类(假设
BookService
是在某处定义的)

当我使用,
def Book=new Book()
实例化
Book
对象时,应该设置
Book.bookService

如果是这样,如果我想注入外部服务(或类似服务的组件),该怎么办?例如,如果有一个ISBNAPI客户机可用,我能期望grails以同样的方式注入它吗?例如,假设客户机是
IsbnApi
,我如何像其他服务一样自动注入?下面的代码行吗

class Book {

    @Transient
    @Autowire
    IsbnApi isbnApi

}
根据前面对这个问题的回答,我已经这样定义了域类:

class Book {

    static transients = ['isbnApi']

    IsbnApi isbnApi

}
现在,这可能就是我所需要的,但我还想测试自动注入是否可以工作,即使不需要运行应用程序。在我的单元测试中,我必须手动设置模拟“服务”

IsbnApi isbnApi = Mock()
Book book = new Book()
book.isbnApi = mockIsbnApi
我试图通过将测试移动到
test/integration
来检查自动注入,并使用
doWithSpring
设置bean

def doWithSpring() {
    isbnApi = (InstanceFactoryBean, mockIsbnApi, isbnApi)
}

void "test automatic injection"() {
    given:
    IsbnApi isbnApi = Mock()
    Book book = new Book()
    //removed: book.isbnApi = mockIsbnApi

    expect:
    book.isbnApi //this fails
}
我还从中找到了其他信息。特别是,

请注意,由于您使用的是“def”,因此不需要将其添加到 瞬态列表。您正在尝试从静态方法访问它吗? 它是一个实例字段,因此您只能从实例访问它


按照惯例,Grails服务自动成为依赖项注入的候选对象(=它们可以被注入到其他类中)。如果您想创建其他类,必须将它们添加到
conf/spring/resources.groovy

例如:

请查看文档部分

为了确保字段不被视为持久属性,可以使用静态
瞬态
字段

例如:

class User {
  def grailsApplication
  static transients = ['grailsApplication']
}

除了已经接受的答案之外,从grails 3.2.x开始,您需要在映射块中的域ojbect上或在应用程序配置中全局启用自动连接

class Book {

    static transients = ['isbnApi']

    IsbnApi isbnApi

    static mapping = {
        autowire true
    }
}
默认情况下,它被禁用以提高读取性能,因此最好找到替代方法,而不是启用它


您的IsbnApi存储在哪里?groovy/src?它可以在任何地方:
src/groovy
,或者来自另一个jar,等等。这足够让Grails不会将
def isbnApi
误认为是一个持久性属性吗?如果Grails在
resources.groovy
中找到它,它是否会自动将其视为注入属性而不是持久属性?我如何通过单元测试来验证这一点?您可以使用
瞬态
字段来验证这一点(更新了答案)是否有办法测试这一点
doWithSpring
在我调用时似乎不起作用,例如,
Book Book=new Book()
。您能更具体一点吗?你想测试什么?我不认为在单元测试中调用
doWithSpring
。也许它在集成测试中被称为。在单元测试期间,您没有spring应用程序上下文,因此依赖项注入不起作用。您应该看看testind文档:我想为服务设置一个模拟行为来测试域类。我希望能够自动注入模拟服务,就像它在实际运行的应用程序中一样,这样我就可以验证一切是否按预期工作。
class User {
  def grailsApplication
  static transients = ['grailsApplication']
}
class Book {

    static transients = ['isbnApi']

    IsbnApi isbnApi

    static mapping = {
        autowire true
    }
}