5

我正在构建一个 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中无法完成的事情吗?或者有人可以提供任何建议吗?

谢谢

4

5 回答 5

4

我过去也遇到过类似的问题,但前提是这两种服务都是事务性的。如果可以使其中至少一个成为非事务性的,那么它应该按原样工作。如果那是不可能的,那么后备是做一种“后期绑定”

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

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

这将在应用程序上下文中查找barService它的使用点,而不是FooService创建点。

于 2012-08-31T11:30:52.017 回答
3

服务可以被另一个服务调用,但在初始化时是不可能的。如果要实现这个,方式应该是这样的。

class fooService{
    def barService

    def getIt(){
        ...
    }

    def anotherFooMethod(){

        barService.doIt();
    }
}

class barService{
    def fooService


    def doIt(){
        ...
    }

    def anotherBarMethod(){

        fooService.getIt();
    }
}
于 2012-08-31T11:50:09.820 回答
2

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

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

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

于 2013-11-24T08:49:59.113 回答
1

那不是有效的代码,所以很难知道到底发生了什么。doIt()getIt()调用在构造函数中吗?如果是这样,请更改服务以实现org.springframework.beans.factory.InitializingBean并执行方法中的调用afterPropertiesSet

于 2012-08-31T11:27:36.777 回答
0

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

让我们称它为 firstService 和 secondService。

secondService 类的代码更改

protected def firstService 
def grailsApplication 

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

Bootstrap.groovy 中的代码更改

def secondService

def init = { servletContext ->

    secondService.initialize()
...
..
于 2013-07-19T07:24:52.610 回答