Grails服务使用来自其他服务的方法

时间:2012-08-31 08:59:39

标签: grails service

我正在构建一个grails应用程序,在尝试在不同的服务中实现服务时遇到了问题。这两种服务都使用另一种服务中定义的方法,例如

class fooService{
    def barService
    barService.doIt()

    def getIt(){
    ...
    }
}

class barService{
    def fooService
    fooService.getIt()

    def doIt(){
    ...
    }
}

当我运行应用程序并转到使用方法的位置时,会出现此错误;

Error creating bean with name 'fooService': 
org.springframework.beans.factory.FactoryBeanNotInitializedException: FactoryBean is 
not fully initialized yet

这是不能用grails做的事情吗?或者任何人都可以提供任何建议吗?

由于

5 个答案:

答案 0 :(得分:4)

我过去曾遇到过类似的问题,但只有当两种服务都是交易性的时候才会出现。如果有可能使其中至少有一个是非事务性的,那么它应该按原样运行。如果那是不可能的,那么后备就是做一种“后期绑定”

class FooService {
  def grailsApplication
  private getBarService() {
    grailsApplication.mainContext.barService
  }

  public methodThatUsesBarService() {
    barService.doSomething()
  }
}

这将在应用程序上下文中使用barService,而不是在FooService创建的位置。

答案 1 :(得分:3)

服务可以由其他服务调用,但在初始化时不可能。如果你想实现这个,那就应该是这样的。

class fooService{
    def barService

    def getIt(){
        ...
    }

    def anotherFooMethod(){

        barService.doIt();
    }
}

class barService{
    def fooService


    def doIt(){
        ...
    }

    def anotherBarMethod(){

        fooService.getIt();
    }
}

答案 2 :(得分:2)

所有这些答案都非常出色,并展示了如何通过框架处理问题。虽然,当我遇到这个问题时,我意识到如果我绝对必须让服务相互调用并引发冲突,那么我的计划和体系结构必定存在缺陷。我没有找到解决办法,而是采取了一种稍微复杂一点的前进方法 - 我进行了重组。我将有问题的方法从服务类移到另一个服务类中。它需要一些重构,重新思考和复制/粘贴技能,但我认为应用程序更适合它。

我不是说这比其他答案更好。我说,这一次,通过这个项目,重构是一个更好,更快,更简单的解决方案。我强烈推荐它。

更新 我们的最终策略是将所有“实用程序”服务函数重构为baseService类,然后让需要实用程序服务的所有其他服务扩展为baseService。新政策是避免将服务注入其他服务,除非出现一些不允许我们遵循这种继承模式的情况。这将为我们提供更清晰的代码库,而不是意外注入的意大利面条。另外,它消除了这个错误的出现。

答案 3 :(得分:1)

这不是有效的代码,因此很难知道究竟发生了什么。构造函数中是doIt()getIt()调用吗?如果是,请更改服务以实施org.springframework.beans.factory.InitializingBean并使用afterPropertiesSet方法进行调用。

答案 4 :(得分:0)

您可以使用以下方法处理循环引用 -

让我们称之为firstSerivce和secondService。

secondService类的代码更改

protected def firstService 
def grailsApplication 

def initialize() {
    this.firstService = grailsApplication.mainContext.firstService 
}

Bootstrap.groovy中的代码更改

def secondService

def init = { servletContext ->

    secondService.initialize()
...
..