我可以将静态方法注册为Guava EventBus订户吗? - java

我有一个应用程序Config对象,该对象从多个来源(.properties文件,数据库表,操作系统等)收集信息,并将其提供给应用程序的其余部分,就好像它们是java.util.Properties一样,例如:

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

如上所示,它们通常以静态方式存储,因此它对于类的所有实例始终可用,而不必不断地获取它。

我也有一种方法告诉该(网络)应用程序重新加载这些“属性”,以便我可以在运行时重新配置该应用程序而无需重新启动。

我想做的是向Guava EventBus注册以订阅我的“ ConfigurationChangeEvent”,这样当我使用重新加载功能时,该类可以更新此devToAddress
在某些情况下,这可能是仅具有静态方法的静态类,而静态方法仍需要应用程序Config信息,因此我不必依靠实例来完成更新静态变量的工作。

我试过的是:

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)方法?

参考方案

不,您不能直接向static注册EventBus方法。首先,我强烈建议您尝试避免这样做。像SampleMailer中一样,静态是一种气味。

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

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

但同样,它实际上应该实际上是一个开始的实例方法。

编辑:嗯,看起来EventBus会在给定该类实例的情况下注册一个静态方法。不过,我不建议您利用这一点:EventBus基于对象实例作为订户的注册,而静态订户方法对此有些奇怪。

Java:线程池如何将线程映射到可运行对象 - java

试图绕过Java并发问题,并且很难理解线程池,线程以及它们正在执行的可运行“任务”之间的关系。如果我创建一个有10个线程的线程池,那么我是否必须将相同的任务传递给池中的每个线程,或者池化的线程实际上只是与任务无关的“工人无人机”可用于执行任何任务?无论哪种方式,Executor / ExecutorService如何将正确的任务分配给正确的线程? 参考方案 …

JAVA:字节码和二进制有什么区别? - java

java字节代码(已编译的语言,也称为目标代码)与机器代码(当前计算机的本机代码)之间有什么区别?我读过一些书,他们将字节码称为二进制指令,但我不知道为什么。 参考方案 字节码是独立于平台的,在Windows中运行的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果在Windows x86中编译,则它将仅在Win…

java:继承 - java

有哪些替代继承的方法? java大神给出的解决方案 有效的Java:偏重于继承而不是继承。 (这实际上也来自“四人帮”)。他提出的理由是,如果扩展类未明确设计为继承,则继承会引起很多不正常的副作用。例如,对super.someMethod()的任何调用都可以引导您通过未知代码的意外路径。取而代之的是,持有对本来应该扩展的类的引用,然后委托给它。这是与Eric…

Java:BigInteger,如何通过OutputStream编写它 - java

我想将BigInteger写入文件。做这个的最好方式是什么。当然,我想从输入流中读取(使用程序,而不是人工)。我必须使用ObjectOutputStream还是有更好的方法?目的是使用尽可能少的字节。谢谢马丁 参考方案 Java序列化(ObjectOutputStream / ObjectInputStream)是将对象序列化为八位字节序列的一种通用方法。但…

Java DefaultSslContextFactory密钥库动态更新 - java

我有一个使用org.restlet.engine.ssl.DefaultSslContextFactory的现有应用程序和一个在服务器启动时加载的密钥库文件。我有另一个应用程序,该应用程序创建必须添加的证书服务器运行时动态地更新到密钥库文件。为此,我在代码中创建了证书和私钥,然后将其写入到目录。该目录由bash脚本监视,该脚本检查是否有新文件,如果出现,它将…