我正在构建一个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做的事情吗?或者任何人都可以提供任何建议吗?
由于
答案 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。
protected def firstService
def grailsApplication
def initialize() {
this.firstService = grailsApplication.mainContext.firstService
}
def secondService
def init = { servletContext ->
secondService.initialize()
...
..