2014-04-08 37 views
2

我有從多個來源收集信息的應用程序配置對象 - .properties文件,數據庫表,操作系統,等等 - 使得這個提供給應用程序的其餘部分,如果他們java.util.Properties,例如:我可以將靜態方法註冊爲Guava EventBus訂戶嗎?

private static String devToAddress = Config.getConfig().getProperty("testAddress"); 

這些經常被存儲,如上所示,作爲一個靜態的,所以它總是可用於一個類的所有實例,而無需不斷地獲取它。

我也有辦法告訴這個(網絡)應用程序重新加載這些「屬性」,所以我可以重新配置應用程序,而不需要重新啓動運行。

我想要做的就是註冊我的Guava EventBus來訂閱我的「ConfigurationChangeEvent」,這樣當我使用我的重新加載功能時,班級可以更新這個​​。 在某些情況下,這可能是一個只有靜態方法的靜態類,它仍然需要應用程序配置信息,所以我不一定指望有一個實例來完成更新靜態變量的工作。

我想這是什麼:

package com.sample.mw; 

import com.google.common.eventbus.Subscribe; 

import com.example.mw.events.ConfigurationChangeEvent; 
import com.example.mw.events.EventDispatcher; 
import com.example.mw.Config; 

public class SampleMailer 
{ 
    private static String devToAddress; 

    // constructor(s) 
    public SampleMailer() 
    { 
     // ... 
    } 

    // instance methods 
    // ... 

    // static methods 
    public static String getTheAddress() 
    { 
     return devToAddress; 
    } 

    @Subscribe 
    public static void loadConfig(ConfigurationChangeEvent cce) 
    { 
     devToAddress = Config.getConfig().getProperty("testAddress"); 
    } 

    // static/class registration with the event bus 
    static 
    { 
     loadConfig(null); // initial config load without an event 
     // 'EventDispatcher' is my singleton that encapsulates the EventBus 
     EventDispatcher.getDispatcher().register(SampleMailer.class); // <-- not sure what to register here 
    } 
} 

的問題是(A)這是可能的呢?你能靜態註冊Guava EventBus嗎? (b)什麼對象我會傳遞給EventBus .register(Object object)方法嗎?

+0

呃,你爲什麼不創建一個單身呢? – fge

+1

簡短的回答是:不。一個'Class'對象不能以這種方式工作。這將是很好,對稱,但有些語言可以工作。不過,我很害怕。 – biziclop

回答

5

不,您不能直接註冊static方法EventBus ...不是。首先,我強烈建議儘量避免這種需求。像你在SampleMailer一樣的靜態是一種氣味。

這就是說,有在這裏使用匿名內部類是一個非常簡單的解決方法:

eventBus.register(new Object() { 
    @Subscribe 
    public void loadConfig(ConfigurationChangeEvent cce) { 
    SampleMailer.loadConfig(cce); 
    } 
}); 

但同樣,它應該可能是對的東西,開始與一個實例方法。

編輯:咦,貌似EventBus註冊考慮到類的實例的靜態方法。不過,我不建議利用這一點:EventBus是基於對象實例的註冊作爲訂戶,而靜態訂戶方法與此有些奇怪地相互作用。

+0

在真實生活中,像'devToAddress'這樣的例子不是狀態,並且沒有這樣的getter - 它本質上是一個嚴格在「SampleMailer」內部使用的緩存配置項;感謝您的快速和簡潔的答案。 –

1

以下是ColinD的回答,我發現番石榴@Subscribe註釋完全開心註冊並調用靜態方法,但它需要實例通過註冊。 訣竅是你不想多次註冊訂閱的靜態方法,對於每個實例,你只需要註冊一次,所以類loadConfig()方法(下面)在重新加載時不會被調用100次。

這個稍微重寫的例子更好地演示了我如何實際使用我的配置項目;沒有getter,並且這個Class之外的世界從不會看到config vars的「狀態」。

package com.sample.mw; 

import com.google.common.eventbus.Subscribe; 

import com.example.mw.events.ConfigurationChangeEvent; 
import com.example.mw.events.EventDispatcher; 
import com.example.mw.mail.Mailer; 
import com.example.mw.Config; 

public class SampleMailer 
{ 
    private static boolean registered = false; 

    private static String devToAddress; 
    private static boolean override; 

    // constructor(s) 
    public SampleMailer() 
    { 
     if (!registered) // could be protected with synchronized() block 
     { 
      // 'EventDispatcher' is my singleton that encapsulates the EventBus 
      // if you register 'this' instance it will find the annotated static method. 
      EventDispatcher.getDispatcher().register(this); 
      registered = true; 
     } 
    } 

    // instance methods 
    public void performAction(String toAddress) 
    { 
     doSomething(override ? devToAddress : toAddress); 
    } 

    private void doSomething(String toAddress) 
    { 
     Mailer.sendAnEmailToTheAddress(toAddress, getEmailText()); 
    } 

    @Subscribe 
    public static void loadConfig(ConfigurationChangeEvent cce) 
    { 
     Config config = Config.getConfig(); 
     devToAddress = config.getProperty("testAddress"); 
     override = Boolean.parseBoolean(config.getProperty("overrideMailDestination")); 
    } 

    // static/class initial load 
    static 
    { 
     loadConfig(null); // initial config load without an event 
    } 
} 

這更接近真實世界的使用;雖然仍然只是示例代碼,但它確實展示瞭如何靜態處理guava EventBus調用。

相關問題