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

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

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

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

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

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

那么如何处理这种情况呢?

更新:

它接缝Guice无法提供以下function:

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

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

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

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

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

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

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

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

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

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

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