2009-12-22 55 views
0

我的意大利麪怪獸從幾種不同的SOAP服務中使用XML,並且每種服務的URL都被硬編碼到應用程序中。我正在取消該硬編碼,並將這些URL存儲在一個屬性文件中。Singleton在Java Web應用程序中讀取屬性文件;正確的做法?

在讀取屬性文件而言,我想涵蓋根據需要可被引用一個Singleton該邏輯。

更改此:
accountLookupURL ="http://prodServer:8080/accountLookupService";

要這樣:
accountLookupURL =urlLister.getURL("accountLookup");

的辛格爾頓將被包含在URLLister中內。

我傾向於迴避Singleton模式了,只是因爲我已經沒有使用它,之前。我在正確的軌道上,在這裏?

謝謝!
IVR復仇者

回答

0

要重申顯而易見的,當所有的客戶端代碼應該與類的單個實例對話時使用單例。因此,使用Singleton IFF,您肯定不會一次加載多個屬性文件。就我個人而言,我希望能夠擁有該功能(加載多個屬性文件)。

+0

使用單不排除加載多個屬性文件一次......我有一個使用一個單集中訪問多個屬性文件(在我的情況實際上是把ResourceBundle)一些代碼。也許你的意思是多個屬性文件包含相同屬性名稱的定義? – Nate 2009-12-22 20:58:04

+0

對,如果我加載了多個屬性文件,我不會擔心名稱衝突,因爲系統不應該(一定)假定他們之間有任何關係。 – danben 2009-12-22 21:05:49

+0

此外,即使沒有名稱衝突,您可能希望對屬性集合進行邏輯分離(即從不同實例訪問集合)。你可以命名空間他們,但我不會爲此瘋狂。 – danben 2009-12-22 21:06:55

0

單身是可變的靜態因此也是邪惡的。 (假設一個合理有用的「單例」定義

任何使用靜態(傳遞關係)的代碼都有幾乎所有其他的假設(在這種情況下,是一個web服務器和互聯網)。是不好的設計,糟糕的設計使得很多方面變得糟糕(依賴性,易懂性,測試性,安全性等)。

作爲一個例子,停止在沙盒中使用JUnit 3的晚期版本的唯一方法是加載配置文件中的一個靜態初始化器。如果它從上面使用參數化,就不會有任何問題。

+0

-1沒有解決問題或提供任何信息的圓形解釋 – danben 2009-12-22 21:02:08

3

你還沒有說爲什麼你只需要任何的一方面,這是其中W生病得到的URL。如果這隻涉及閱讀屬性文件,我不認爲你只需要一個。在我看來,有兩個線程同時讀取相同的屬性文件根本不是問題。

除非你在想有一些對象只讀取屬性文件一次,然後供將來使用緩存的內容。但這是一個Web應用程序,對不對?所以處理這個問題的方法是在應用程序啓動時讀入屬性,並將它們存儲在應用程序上下文中。只有一個應用程序上下文,所以你的「只有一個」對象。

+0

我不確定我能否做到這一點,因爲這個應用程序的很大一部分被抽象爲JAR文件,其源不可用於我們。這會帶來什麼? – 2009-12-22 20:52:44

+0

IVR復仇者,你現在如何將屬性傳遞給Jar文件? – Poindexter 2009-12-23 14:57:51

+0

我會想象那些屬性是完全按照你上面描述的來讀取的。但是,閱讀發生在我可以訪問的領域之外。我的代碼擴展了我沒有的源代碼,並且這些類正在讀取特定的屬性。理想情況下,我會更改基類,以便這些URL與現有屬性一樣可用,但我無法訪問基類。然而......--) – 2009-12-23 15:32:02

1

單身適合此方案,但你必須確保你正在做的單身權利。因此,例如,Bozhno建議不是一個單身人士,它是一個醜陋的靜態混合物,不可嘲笑,不易測試,不可注射,並且通常會回來咬你。

可接受的單身只是你有一個明顯的例外,平均班,它是通過其自身或通過一些外部工廠/框架(例如Spring IoC來)保證在只有一個實例存在。如果用第一種方法去,你這樣做

private MyUberSingletonClass() { 
    //..do your constructor stuff, note it's private 
} 

private static MyUberSingletonClass instance = null; 

public static synchronized MyUberSingletonClass instance() { 
    if (instance == null) { 
     instance = new MyUberSingletonClass(); 
    } 
    return instance; 
} 

public String getUberUsefulStuff(){ 
    return "42"; 
} 

這是可以接受的,如果你不覺得一個工廠,否則的需要,並在應用中不使用任何IoC容器(好主意考慮使用一個雖然)。請注意與Bozhno示例的區別:這是一個很好的香草類,其中唯一的靜態是實例var和返回它的方法。還要注意延遲初始化所需的synchronized關鍵字。

更新:帕斯卡建議這個即將在下面的評論延遲實例單身更好的方式非常酷的帖子:http://crazybob.org/2007/01/lazy-loading-singletons.html

+1

你可能想讀這個:http://crazybob.org/2007/01/lazy-loading-singletons.html – 2009-12-22 21:15:02

+0

非常非常好!感謝Pascal。比同步的成語更整齊。我只是想知道,從1.3開始,對於所有的JVM來說這種行爲是否一致 - 我最近一直在做Blackberry的開發,正如你所知,CLDC是一個婊子。 – 2009-12-22 21:54:36

1

根據您的建議,以及我認爲我沒有像希望的那樣訪問此應用程序的許多事實(其中很多是在編譯代碼中抽象出來的),下面是我的解決方案熟了。這當然是一個存根,需要用更好的異常處理等來充實。

public class WebServiceURLs { 

    private static class WebServiceURLsHolder 
    { 
    public static WebServiceURLs webServiceURLs = new WebServiceURLs(); 
    } 

    private Properties webServiceURLs; 


    public WebServiceURLs() 
    { 
    try 
    { 
     Properties newURLProperties = new Properties();  
     InputStreamReader inputStream = new InputStreamReader(
      FileLoader.class.getClassLoader().getResourceAsStream("../../config/URLs.properties")); 
     newURLProperties.load(inputStream); 
     webServiceURLs =newURLProperties; 
    } 
    catch (Exception e) 
    { 
     webServiceURLs =null; 
    }   
    } 

    public String getURLFromKey(String urlKey) 
    {  
    if (webServiceURLs==null) 
     return null; 
    else 
     return webServiceURLs.getProperty(urlKey); 
    } 

    public static WebServiceURLs getInstance() 
    { 
    return WebServiceURLsHolder.webServiceURLs; 
    } 

} 

這是一個很好的努力爲我的 「第一次」 單身?

感謝,
IVR復仇者

+0

這不完全是一個單身人士。你應該讓WebServiceUrls的一個對象成爲它自己的一個實例變量,並使構造函數保持私有狀態。 getInstance()方法應檢查該對象是否已創建,如果尚未返回,則創建該對象。 – Poindexter 2009-12-23 15:02:03

+0

好的。但它模仿上面Pascal鏈接中詳細描述的結構。這不是我應該採取的方法嗎? – 2009-12-23 15:14:35

相關問題