带有 Play2.4 和 scala 的 Google Guice 的循环依赖错误
Posted
技术标签:
【中文标题】带有 Play2.4 和 scala 的 Google Guice 的循环依赖错误【英文标题】:Circular Dependency Error for Google Guice with Play2.4 and scala 【发布时间】:2015-06-30 13:33:33 【问题描述】:我的应用程序使用 Play 2.4 和 Scala 2.11。我开始转换现有代码以使用 Play 2.4 附带的 Google Guice。
在进行第一组更改后运行我的代码时,我发现我的代码中的一些 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
谁能帮我解决这个错误。
提前致谢
【问题讨论】:
【参考方案1】:快速解决方案
改为注入Provider
:
class BookDAO @Inject()(personDaoProvider: Provider[PersonDAO], ...)
extends HasDatabaseConfigProvider[JdbcProfile]
val personDAO = personDaoProvider.get
def person = personDAO.get(personId)
BookDAO
也是如此。这将开箱即用。 Guice 已经“知道”如何注入 Providers。
更好的方法
将类定义与实现分离。请参阅 Mon Calamari 的回答。
【讨论】:
【参考方案2】:如下定义你的依赖,并从类中提取所有需要的方法到特征:
@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
可以注入代理类并解决循环依赖问题。
更多关于playframework scala
依赖注入here的细节。
【讨论】:
以上是关于带有 Play2.4 和 scala 的 Google Guice 的循环依赖错误的主要内容,如果未能解决你的问题,请参考以下文章
Play 2.4 中的 Global.getControllerInstance 等价物是啥?
如何在 play 2.4 中的 scala 模板中设置类型列表字段的值?