如何用Guice很好地处理构造函数中的检查异常



我的代码是这样的:

class A {
  X x;
  A() {
    Class<? extends X> cls = ...;
    Module module = ...;
    Injector injector = Guice.createInjector(module);
    x = injector.getInstance(cls);
  }
}

具体类型cls仅在运行时确定,在调用此构造函数之前不知道。

我现在的问题是cls的构造函数预计会抛出检查异常,我想处理它们(如果可能的话,不要从ProvisionException中展开它们)。Guice文档说我应该使用抛出提供程序扩展,这在这里似乎很复杂。有没有比这更简单的方法:

interface MyCheckedProvider<T> extends CheckedProvider<T> {
  T get() throws MyCheckedException;
}
class XImplProvider implements MyCheckedProvider<X> {
  @Inject dependency1;
  @Inject dependency1;
  X get() throws MyCheckedException {
    return new XImpl(dependency1, dependency2);
  }
}
class ProviderHolder {
  @Inject MyCheckedProvider<X> provider;
}
class A {
  X x;
  A() {
    Class<? extends MyCheckedProvider<X>> providerClass = ...;
    Module module = new AbstractModule() {
      void configure() {
        ...
        ThrowingProviderBinder.create(binder())
          .bind(MyCheckedProvider.class, X.class)
          .to(providerClass.class);
      }
    };
    Injector injector = Guice.createInjector(module);
    ProviderHolder holder = injector.getInstance(ProviderHolder.class);
    try {
      x = holder.provider.get();
    catch (MyCheckedException e) {
      ...
    }
  }
}

接口MyCheckedProvider是可以的,因为它可以在几个地方重用,但是我需要在每个需要类似东西的地方单独的ProviderHolder类,并且我需要为每个实现X的类提供特定的提供者实现(其中可能有很多)。因此,这比仅仅注入一个XFactory并为每个具体类型编写一个XFactoryImpl(我试图避免这样做)要做更多的工作。

我曾希望我能做一些像

injector.getInstance(new TypeLiteral<MyCheckedProvider<X>>() {});

injector.getCheckedProvider(cls, MyCheckedException.class);

您希望在这里使用Key类,而不是TypeLiteral。那么就不需要ProviderHolder:

Injector injector = Guice.createInjector(module);
MyCheckedProvider<X> provider = injector.getInstance(new Key<MyCheckedProvider<X>>(){});
try {...

最新更新