Java 我可以将静态方法注册为Guava EventBus订阅服务器吗?

Java 我可以将静态方法注册为Guava EventBus订阅服务器吗?,java,guava,Java,Guava,我有一个application Config对象,它从多个源收集信息-.properties文件、数据库表、操作系统等,并使应用程序的其余部分可以使用它,就像它们是java.util.properties,例如: private static String devToAddress = Config.getConfig().getProperty("testAddress"); 如上图所示,这些文件通常存储为静态文件,因此类的所有实例都可以使用它,而不必不断地获取它 我还可以告诉这个(web)

我有一个application Config对象,它从多个源收集信息-.properties文件、数据库表、操作系统等,并使应用程序的其余部分可以使用它,就像它们是
java.util.properties
,例如:

private static String devToAddress = Config.getConfig().getProperty("testAddress");
如上图所示,这些文件通常存储为静态文件,因此类的所有实例都可以使用它,而不必不断地获取它

我还可以告诉这个(web)应用程序重新加载这些“属性”,这样我就可以在应用程序运行时重新配置它,而无需重新启动

我想做的是注册我的Guava EventBus以订阅我的“ConfigurationChangeEvent”,这样当我使用我的重新加载功能时,类可以更新这个
devToAddress
。 在某些情况下,这可能是一个静态类,只有静态方法仍然需要应用程序配置信息,因此我不一定指望有一个实例来更新静态变量

我尝试的是:

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
    }
}
package com.sample.mw;
导入com.google.common.eventbus.Subscribe;
导入com.example.mw.events.ConfigurationChangeEvent;
导入com.example.mw.events.EventDispatcher;
导入com.example.mw.Config;
公共类抽样器
{
私有静态字符串设计;
//建造商
公共样本发送器()
{
// ...
}
//实例方法
//    ...
//静态方法
公共静态头饰()
{
退换衣服;
}
@订阅
公共静态无效加载配置(ConfigurationChangeEvent cce)
{
devtoadress=Config.getConfig().getProperty(“testAddress”);
}
//使用事件总线进行静态/类注册
静止的
{
loadConfig(null);//在没有事件的情况下加载初始配置
//“EventDispatcher”是封装EventBus的单例

EventDispatcher.getDispatcher().register(SampleMailer.class);//不,不能用
EventBus
直接注册
static
方法。首先,我强烈建议不要从一开始就使用它。像
SampleMailer
中的静态是一种气味

也就是说,这里有一个非常简单的解决方法,使用匿名内部类:

eventBus.register(new Object() {
  @Subscribe
  public void loadConfig(ConfigurationChangeEvent cce) {
    SampleMailer.loadConfig(cce);
  }
});
但同样,它很可能是一个实例方法


Edit:Huh,看起来
EventBus
将在给定该类实例的情况下注册静态方法。不过,我不建议利用这一点:
EventBus
基于将对象实例注册为订阅者,静态订阅者方法与之交互有点奇怪。

根据ColinD的回答,我发现Guava
@Subscribe
注释非常乐意注册和调用静态方法,但它需要传递一个实例进行注册。 诀窍是您不想多次注册订阅的静态方法,对于每个实例,您只想注册一次,这样在重新加载时类
loadConfig()
方法(如下)不会被调用100次

这个稍微重写的示例更好地演示了我如何实际使用配置项;没有getter,这个类之外的世界永远看不到配置变量的“状态”

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调用。

Uhm,为什么不创建一个单例呢?简短的回答是:不。一个
Class
对象不是这样工作的。它会很好,而且是对称的,而且有一些语言可以使用它在现实生活中,像示例
devtoadress
这样的东西不是state,也不会有这样的getter——它本质上是一个缓存配置项,严格地在“SampleMailer”内部使用;感谢您快速简洁的回答。