Google guice,覆盖配置

时间:2017-04-30 20:16:41

标签: dependency-injection playframework guice

我正在与Guice合作,并有一个设计问题。我的应用程序包含几个模块:

  • myapp-persistence(JPA实体,DAO,其他与数据库相关的东西)
  • myapp-backend(一些后台守护进程,他们使用myapp-persistence)
  • myapp-rest(取决于myapp-persistence的REST应用程序)

myapp-persistence必须有单独的HibernateSessionFactory。这是通过Hibernate设计的。 没问题我可以用Guice解决它:

class MyAppPersistenceModule extends AbstractModule {

  override def configure(): Unit = {

    bind(classOf[SomeStuff])
    bind(classOf[ClientDao])
    bind(classOf[CustomerDao])
    bind(classOf[SessionFactory]).toProvider(classOf[HibernateSessionFactoryProvider]).asEagerSingleton()

  }

  @Provides
  def provideDatabaseConnectionConfiguration: DatabaseConnectionConfiguration = {
    DatabaseConnectionConfiguration.fromSysEnv
  }

}

DatabaseConnectionConfiguration 传递给该单例的问题。 myapp-persistence模块并不关心如何获得该配置。现在它取自sys变量。

myapp-rest是play-app,它想从application.conf读取conf并使用Guice将其注入其他组件。 myapp-backend或多或少相同。

现在我被锁定了

@Provides
  def provideDatabaseConnectionConfiguration: DatabaseConnectionConfiguration = {
    DatabaseConnectionConfiguration.fromSysEnv
  }

我不明白如何为myapp-rest和myapp-backend灵活配置。

UPD 根据回答,我是这样做的:

定义特征

trait DbConfProvider {
  def dbConf: DbConf
}

Singleton工厂现在依赖于提供者:

class HibernateSessionFactoryProvider @Inject()(dbConfProvider: DbConfProvider) extends Provider[SessionFactory] {
}

myapp-persistence模块使用所有piblic持久性模块DAO公开public guice模块。

myapp-persistence具有仅用于测试目的的模块。 myapp-persistence注入器加载模块如下所述:

class MyAppPersistenceDbConfModule extends AbstractModule {

  override def configure(): Unit = {
    bind(classOf[DbConfProvider]).to(classOf[DbConfSysEnvProvider])
  }

}

DbConfSysEnvProvider从sys env读取数据库连接设置。非生产用例。

Play app拥有自己的conf机制。我已将自定义模块添加到app conf:

# play-specific config
play.modules.enabled += "common.components.MyAppPersistenceDbConfModule"
# public components from myapp-persistence module.
play.modules.enabled += "com.myapp.persistence.connection.PersistenceModule"

我的配置服务:

@Singleton
class ConfigurationService @Inject()(configuration: Configuration) extends DbConfProvider {
...}

1 个答案:

答案 0 :(得分:3)

我不是Play特定设置的专家,但通常这种设计问题可以通过以下方式之一解决:

  1. 没有默认值。从上游模块中删除DatabaseConnectionConfiguration的绑定(myapp-persistence),并根据需要在每个下游模块(myapp-backend,myapp-rest)中定义它。

  2. 默认为覆盖。像你一样保持DatabaseConnectionConfiguration的默认绑定,在那里实现最常见的配置策略。在需要时使用Guice Modules.override(..) API在下游模块中覆盖它。

  3. 跨模块实现统一的配置机制,不依赖于使用的特定框架。 (例如Bootique,建立在Guice之上......虽然没有将它用于Play)。

  4. 我个人更喜欢方法#3,但在没有类似Bootique的情况下,#2是一个很好的替代品。