【问题标题】:How can I get all singleton instances from a Guice Injector?如何从 Guice Injector 获取所有单例实例?
【发布时间】:2012-12-25 18:42:42
【问题描述】:

有没有一种简单的方法来枚举 Guice Injector 已经创建的所有单例实例?或者另一种方法来获取实现特定接口的所有单例?

我想找到所有实现 java.io.Closeable 的单例实例,以便在我的服务关闭时可以干净地关闭它们。

【问题讨论】:

  • 我宁愿不必创建一个引用所有这些对象的“包装器”对象,或者如果可能的话让它们用注入的“更接近”的单例注册自己。 Guice 必须在某处引用所有单例...

标签: java dependency-injection guice


【解决方案1】:

使用 Guice 的 SPI 编写这将相当容易。 Guice 的 Injector 实例公开了一个 getAllBindings() 方法,可以让您遍历所有绑定。

// Untested code. May need massaging.
private void closeAll(Injector injector) {
  for(Map.Entry<Key<?>, Binding<?>> entry : injector.getAllBindings().entrySet()) {
    final Binding<?> binding = entry.getValue();
    if (Closeable.class.isAssignableFrom(
        entry.getKey().getTypeLiteral().getRawType())) {
      binding.accept(new DefaultBindingScopingVisitor<Void>() {
        @Override public Void visitEagerSingleton() {
          Closeable instance = (Closeable) (binding.getProvider().get());
          try {
            instance.close();
          } catch (IOException e) {
            // log this?
          }
          return null;
        }
      });
    }
  }
}

请注意,我只覆盖了visitEagerSingleton,并且您可能必须修改上述内容以处理具有隐式绑定的延迟实例化的@Singleton 实例。另请注意,如果您 bind(SomeInterface.class).to(SomeClosable.class).in(Singleton.class) 您可能需要使 SomeInterface.class 可关闭,但您也可以实例化每个单例(通过将可关闭检查放在范围访问者内)以确定提供的实例本身是否可关闭,而不管键.您还可以对 Binding 的 Key 使用 Reflection 来检查该类型是否可分配给 Closable。

【讨论】:

  • 嗯。这似乎只能找到显式绑定的单例,而不是只用 @Singleton 注释而在模块中没有定义绑定的单例?
  • 对,但由于 getAllBindings 包含惰性绑定,因此您只需实现访问者的 visitScopeAnnotation,为简洁起见,我省略了它。不过,您可能希望明确地绑定您的 Singleton——如果它们有很长的启动时间,您可能会受益于 Guice 的热切实例化,以使您的应用程序的性能更可预测,并减少启动后很长一段时间内出现不满足的依赖错误的机会。
  • 最后我只是做了 entry.value.provider.get() 来获取每个实例并测试 Closable。发送。
  • 这适用于渴望,但对于懒惰的单例 - 我认为作者打算只检查已经实例化的实例,而不是仅仅为了调用其 close() 方法而实例化单例。如果尚未创建,则调用 binding.getProvider() get() 将创建一个新实例
猜你喜欢
  • 1970-01-01
  • 2015-08-19
  • 2018-02-07
  • 2016-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-27
  • 1970-01-01
相关资源
最近更新 更多