Google Guice 与 Play2.4 和 scala 的循环依赖错误

Circular Dependency Error for Google Guice with Play2.4 and scala

我的应用程序使用 Play 2.4 和 Scala 2.11。我开始转换我现有的代码以利用 Google Guice Play 2.4 附带的。

当我 运行 我的代码在进行第一组更改后,我发现我的代码中的一些 DAO 因 循环依赖错误而失败。

例如我有两个 DAO

class BookDAO @Inject()
(protected val personDAO : PersonDAO,
 @NamedDatabase("mysql")protected val dbConfigProvider: DatabaseConfigProvider) extends HasDatabaseConfigProvider[JdbcProfile] {
...
...
val personId = //some id
personDAO.get(personId)
}

class PersonDAO @Inject()
(protected val bookDAO : BookDAO,
 @NamedDatabase("mysql")protected val dbConfigProvider: DatabaseConfigProvider) extends HasDatabaseConfigProvider[JdbcProfile] {
...
...
val bookName= //some id
personDAO.getByName(bookName)
}

我在尝试访问 BookDAO 或 PersonDAO 时遇到以下错误

Tried proxying schema.BookDAO to support a circular dependency, but it is not an interface.
  at schema.BookDAO.class(Books.scala:52)
  while locating schema.BookDAO

谁能帮我解决这个错误。

提前致谢

按如下方式定义您的依赖项,并将所有需要的方法从 class 提取到特征:

@ImplementedBy(classOf[BookDao])
trait IBookDao {
  // abstract defs
}

class BookDao @Inject()(protected val personDAO: IPersonDao, protected val dbConfigProvider: DatabaseConfigProvider) extends HasDatabaseConfigProvider[JdbcProfile] with IBookDao {
}

@ImplementedBy(classOf[PersonDao])
trait IPersonDao {
  // abstract defs
}

class PersonDao @Inject()(protected val bookDAO: IBookDao, protected val dbConfigProvider: DatabaseConfigProvider) extends HasDatabaseConfigProvider[JdbcProfile] with IPersonDao {
}

如您所见,每个 dao 实现一个特征,并且所有 dao 依赖项都由 trait 注入。这使 Guice 有可能注入代理 class 并解决循环依赖问题。

有关 playframework scala 依赖项注入的更多详细信息 here

快速解决

改为注入 Provider

class BookDAO @Inject()(personDaoProvider: Provider[PersonDAO], ...)
extends HasDatabaseConfigProvider[JdbcProfile] {
  val personDAO = personDaoProvider.get
  def person = personDAO.get(personId)
}

BookDAO也是如此。这将开箱即用。 Guice 已经 "knows" 如何注入供应商。


更好的方法

将 class 定义与实现分离。请参阅 Mon Calamari 的回答。