确保模块仅在Guice中加载一次

时间:2013-12-22 23:31:45

标签: java guice

必须处理Guice,我想知道我应该如何处理模块方面的依赖。

在Guice中,每个模块都由一个实例提供。因此,如果我有一个需要某个服务的模块,它会创建一个模块,为该服务添加一个绑定并安装它(binder.install(module))。

现在我有两个独立的模块,完全可以独立使用,并且都安装相同的数据库模块。

独立使用这两个模块不会出现问题,但如果两个模块在同一个应用程序中使用会发生什么?数据库模块将由两个模块独立加载,但不能正确。

如果特定类型已经绑定,有没有办法询问活页夹?我不能使用getProvider来检查它,因为所有返回的都是LookupProvider,无论某些东西是否已经绑定。

那么如何处理这种情况?

更新

它接缝Guice无法提供以下功能:

  1. 检查是否已加载给定模块。
  2. 检查给定的课程是否已被绑定。
  3. 使用配置中的提供程序可以执行分布式配置(模块能够配置要提供的对象)。

3 个答案:

答案 0 :(得分:12)

Guice有两个功能来处理这种情况。第一个是模块重复数据删除。这意味着如果安装了两个等效的模块(equals()hashCode()),则只运行一个configure()方法。但是,这种解决方案有点脆弱,因为它无法在SPI转换中存活,Modules.override()等等。

第二个和IMO更好的解决方案是绑定重复数据删除。这意味着Guice将接受完全重复的绑定。因此,如果您的模块执行bind(Interface.class).to(Implementation.class),那么它的configure()方法运行两次并不重要,因为Guice将处理重复绑定就好了。

答案 1 :(得分:0)

由于Guice不支持某些必需的功能,因此必须模拟它。 multibinder代码提供了一个想法。我目前使用的另一个想法是使用反射在注射器构建过程中找到最顶端的粘合剂。知道这个绑定器可以轻松添加所需的元信息并跟踪某些对象。

一旦构建过程完成,这些元信息将被删除。

通常一次只建一个注射器,但要确保我们应该防止这种情况发生。

所以看一下最单一的Binder实现(RecordingBinder)。它提供了一个我们可以走到根绑定器元素的字段父级。通常Guice将使用单个大多数绑定器,但在私有模块的情况下。

如果你能确保一次只构建一个Guice注入器,那么另一个不太安全但没有反射的想法是使用本地线程。

能够识别构建过程并跟踪一次使用哪些构建器,可以将任何类型的附加逻辑添加到guice中,例如防止两次安装依赖项。

答案 2 :(得分:0)

绑定重复数据删除看起来已在Guice 4.0中添加

https://github.com/google/guice/commit/c34e0185fcf508a890c6cd13bdafeb505c3e9e8a