2014-09-22 63 views
1

我以前从未使用Grails服务,但根据我的Web搜索,它们可以注入到域对象中。所以,如果我有以下的领域类(假设BookService某处定义),如何向Grails域对象注入类似服务的组件?

class Book { 

    BookService bookService 

} 

当我实例化一个对象Book使用,def book = new Book()book.bookService应设置?

如果是这样的话,如果我想注入外部服务(或类似服务的组件),该怎么办?例如,如果有可用的ISBN API客户端,我希望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设置豆。

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 
} 

我还从this answer to a similar question找到了其他信息。特别是,

注意因为你使用“高清”你不需要将它添加到 瞬变列出。你是否试图从静态方法访问它? 这是一个实例字段,因此您只能从实例访问它。

+0

在哪里存储您的IsbnApi?常规/ src目录? – 2014-09-22 06:05:57

+0

它可以在任何地方:'src/groovy',或来自另一个jar等。 – 2014-09-22 08:49:42

回答

2

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

例如为:

import foo.bar.IsbnApi 

beans = { 
    isbnApi(IsbnApi) 
} 

看一看的Bean Builder文档部分。

要确保您的字段不被视为永久性属性,您可以使用静态transients字段。

例如:

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

transients documentation

+0

这足以让Grails不会将'def isbnApi'作为持久属性吗?如果Grails在资源中找到它。groovy'会自动将它视为注入属性而不是持久性属性?我如何通过单元测试来验证? – 2014-09-22 08:52:20

+0

你可以使用'瞬变'字段(更新答案) – micha 2014-09-22 09:34:15

+0

有没有办法测试这个?当我打电话时,'doWithSpring'似乎不起作用,例如'Book book = new Book()'。 – 2014-09-22 09:59:40