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 的回答。
我的应用程序使用 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 的回答。