Guice具有两个功能来处理这种情况。第一个是模块去重。这意味着如果安装了两个等效的模块(由equals()
和hashCode()
确定),只有一个configure()
方法将运行。然而,这种解决方案有些脆弱,因为它不能经受SPI转换、Modules.override()
等。
第二个,也是我认为更好的解决方案,是绑定去重。这意味着Guice将接受完全重复的绑定。因此,如果您的模块执行bind(Interface.class).to(Implementation.class)
操作,即使它的configure()
方法运行了两次,Guice也可以很好地处理重复绑定。
Guice 4.0 中似乎添加了绑定去重功能
https://github.com/google/guice/commit/c34e0185fcf508a890c6cd13bdafeb505c3e9e8a
由于Guice不支持某些所需功能,因此必须进行仿真。 multibinder代码提供了一个想法。我目前使用的另一个想法是在注入器构建过程中使用反射查找最顶层绑定器。知道这个绑定器后,可以轻松添加所需的元信息并跟踪某些对象。
这些元信息将在构建过程完成后被删除。
通常一次只构建一个注入器,但为了确保我们应该防止这种情况发生。
因此,请查看单个最重要的Binder实现(RecordingBinder)。它提供了一个parent字段,我们可以遍历到根绑定器元素。通常,Guice将使用单个最重要的绑定器,但在私有模块的情况下除外。
另一个想法并不那么安全,但不需要反射,即使用线程本地变量,如果您可以确保一次只构建一个Guice注入器。
能够识别构建过程并跟踪同时使用的构建器,人们就能够向Guice添加任何类型的附加逻辑,例如防止重复安装依赖项。