2013-09-24 69 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方法...