2013-09-24 33 views
2

吉斯提供绑定到供应商的方式:如何绑定到Guice中的CheckedProvider?

bind(A.class).toProvider(AProvider.class); 

虽然如果我的供应商需要抛出一个异常,那么它似乎CheckedProvider是一个正确的基本接口:

public interface ConfigCheckedProvider<T> extends CheckedProvider<T> { 
     T get() throws ConfigException; 
    } 

    public AProvider implements ConfigCheckedProvider<A> { ... } 

但现在我的一些类需要注入A的实例。而我无法改变。但它看起来像Provider方法不接受CheckedProvider类型。

我如何使用基于CheckedProvider的提供者来注入实例而不是提供者

+0

这不会破坏'@ CheckedProvider'的目的吗?如何注入一个实例抛出异常?我认为如果你想注入实例,你必须切换到一个普通的'Provider'实现(并且只抛出运行时异常)。 – condit

+0

@CheckedProvider不适用于类的提供者。普通的旧提供程序不允许异常抛出。问题是:如何让提供者在单独的类中(大的初始化逻辑)并允许此提供者抛出异常。但最终目标不是注入提供者,而是注入提供者提供的实例。 – vladimir

+0

@vladimir,你不能那样做。被检查的提供者完全是为了不直接注入对象而创建的,因为它们的创建可能会失败,并且这个失败必须由程序代码来处理。如果您不想处理创建失败,那么您可以使用普通提供程序,并在某些运行时异常中将所有已检查的异常包装在'get()'中。 –

回答

5

按照您的要求,我发布我的评论作为答案。


如果你有一个类T和检查提供商TProvider extends CheckedProvider<T>,你不能只是T注:

@Inject 
SomeClass(T t) { // Won't work 
    ... 
} 

,你就能够知道如果使用普通Provider<T>。这是有意完成的。当一个对象的创建可能因特定类型的异常而失败时,需要检查提供者,并且这个失败必须由用户代码来处理。普通提供商没有这种功能。

Provider<T>不允许从其get()方法抛出检查异常,并抛出任何unchecked异常可包裹成ProvisionException,所以你不能可靠地抓住你的例外。另外,如果您直接注入T并且您的提供商的方法get()方法失败,那么您将在注入过程中出现错误,这可能会导致难以理解的堆栈跟踪(尤其是如果您没有直接使用Injector)或者甚至不需要它们。

检查的提供程序允许您向提供程序抛出预先定义的例外类型,并且这些例外保证将原样传递给在您的检查提供程序上调用get()的代码。通过这种方式,您可以可靠地捕获它们,但是作为回报,您将无法直接注入由提供者创建的对象。

请参阅this manual关于投掷和检查提供商的更多背景信息。

0

很明显,我所要求的是故意不提供的guice。然而,可能会编写自己的检查提供程序,它将实现提供程序,因此可用于提供程序绑定。

比如我有问题提供了以下经过提供商可能是有意义的:

public abstract class MyCheckedProvider<T, E extends Exception> 
         implements Provider<T> { 

    public abstract T getChecked() throws E; 

    @Override 
    public T get() { 
     try { 
      return getChecked(); 
     } catch (Exception e) { 
      throw new ProvisionException("Checked provider threw exception", e); 
     } 
    } 
} 

有了这个MYPROVIDER的AProvider可能看起来像:

public class AProvider extends MyCheckedProvider<A, ConfigException> { 
    @Override 
    public A getChecked() throws ConfigException { 
     ... 
    } 
} 


bind(A.class).toProvider(AProvider.class); 

所有这只有当你想如果提供程序中出现错误,则抛出ProvisionExceptions。对于其他的逻辑MyProvider显然应该有其他的实现get方法...