2010-10-25 82 views

回答

37

Supplier接口只是一個無參數函數的抽象,它返回一個值...它是一個獲取某個對象的實例或實例的手段。既然它是如此普遍,它可以用於許多事情。 Jared解釋了Multimaps工廠如何利用它作爲工廠來創建某種類型的值的新實例Collection

鑑於接口的簡單性,它還允許通過將其包裝在另一個以某種方式改變其行爲的另一個Supplier的行爲的一個非常強大的裝飾。記憶就是一個例子。我自己使用Suppliers.memoizeWithExpiration方法作爲一種簡單的方法,使得某些數據在特定時間段內最多隻能從服務器讀取一次。

我還建議看看Guice以及Provider界面是如何使用它的。 Provider完全等同於Supplier,它是Guice工作的核心。

  • Provider允許用戶定義創建給定類的新對象的自定義方式。用戶可以編寫一個get()方法可以執行任何需要的代碼來創建一個新的對象,所以它們不僅限於讓Guice使用構造函數來創建對象。在這裏,他們正在使用它爲對象的新實例定義工廠的自定義
  • Guice允許注入任何依賴關係的Provider。這可能會在每次調用get()時返回一個新實例,或者它可能始終會返回單個實例或其中的任何實例,具體取決於Provider所表示的綁定的作用域範圍。這也允許依賴關係的「懶惰實例化」...在Provider給出了一個類,而無需實際提前創建對象創建對象手段。對象的一個​​實例不需要被創建,直到調用get()
  • 如上所示,Provider S型在吉斯劃定範圍的基礎。如果你看一看的Scope界面,你會發現它的一個方法Provider<T> scope(Key<T> key, Provider<T> unscoped)中的Provider條款定義。此方法需要東西,創建一個對象(在Provider<T> unscoped)的一個新實例,並返回基於該施加任何政策的範圍定義,有可能返回對象的一些緩存的實例,而不是創建一個新的一個Provider<T>。默認的NO_SCOPE範圍只是沿着unscoped提供者傳遞,這意味着每次都會創建一個新實例。該SINGLETON範圍緩存第一次調用unscoped.get()的結果,然後返回單一實例,從而確保依賴於單範圍的對象上的一切獲取對單一對象的引用。請注意,由SINGLETON範圍內的方法返回的Provider方法確實與方法相同Suppliers.memoize返回的Supplier(儘管它稍微複雜一些)。
7

這是一種提供間接對象的方法。每次調用Supplier.get() is時,您可能都想提供另一個對象。

例如,我有一個叫做SmtpMailSender的單例類,它爲smtp服務器提供一個主機名。但是,主機名可以在運行時更改,因此不需要執行String hostname,而是需要Supplier<String> hostname

0

Suppliers類和我猜的方法會有莫名其妙地回答你的問題。

14

我們包括番石榴供應商的主要原因是支持Multimaps方法生成任意屈德寧,如

public static <K,V> Multimap<K,V> newMultimap(Map<K,Collection<V>> map, 
    Supplier<? extends Collection<V>> factory) 

供應商創建一個包含給定鍵的所有值的集合。無論何時將鍵值對與不在Multimap中的鍵一起存儲,Multimap都會使用供應商。

+0

你知道在供應商mnemonize如果是的話請給一個樣嗎?。 – Emil 2010-11-10 07:55:06

+1

@Emil:'memoize'可以使用例如[這裏](http://stackoverflow.com/questions/3636244/thread-safe-cache-of-one-object-in-java/3636791#3636791) – maaartinus 2011-09-14 08:27:59

1

該類的另一個重要用途是解耦 - 如果一個組件只使用另一個組件獲取值,則不依賴於具體實現,而是依賴於該接口。

無論如何,有一些示例代碼在這裏:http://www.slideshare.net/tfnico/google-guava