当前位置: 首页 > 知识库问答 >
问题:

我可以将静态方法注册为Guava EventBus订阅者吗?

史飞尘
2023-03-14

我有一个应用程序配置对象,它从几个来源收集信息。属性文件、数据库表、操作系统等。—并使其对应用程序的其余部分可用,就像它们是< code > Java . util . properties 一样,例如:

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

如上所示,这些通常被存储为静态的,因此它总是可用于类的所有实例,而无需不断获取它。

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

我想做的是向我的Guava EventBus注册以订阅我的“ConfigurationChangeEvent ”,这样当我使用我的重新加载特性时,该类可以更新这个< code>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
    }
}

问题是(a)这到底有可能吗?你能静态注册Guava EventBus吗?(b)我要传递什么对象给EventBus。寄存器(对象对象)方法?

共有2个答案

欧浩淼
2023-03-14

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

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

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

阎志义
2023-03-14

否,您不能使用事件总线注册静态方法...不直接。首先,我强烈建议您尝试避免这样做。像您在样品邮件中那样的静态状态是一种气味。

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

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

但同样,它应该真的是一开始就是某种东西的实例方法。

Edit:嗯,看起来< code>EventBus将注册一个静态方法,给出该类的一个实例。尽管如此,我还是不建议利用这一点:< code>EventBus基于将对象实例注册为订阅者,静态订阅者方法与它的交互有点奇怪。

 类似资料:
  • 本文向大家介绍Oracle Listener 动态注册 与 静态注册,包括了Oracle Listener 动态注册 与 静态注册的使用技巧和注意事项,需要的朋友参考一下 一.什么是注册 注册就是将数据库作为一个服务注册到监听程序。客户端不需要知道数据库名和实例名,只需要知道该数据库对外提供的服务名就可以申请连接到数据库。这个服务名可能与实例名一样,也有可能不一样。   在数据库服务器启动过程中,

  • 问题内容: 我想知道非静态方法如何修改静态变量。我知道静态方法只能访问其他静态方法和静态变量。但是,另一面是真的吗?非静态方法只能访问非静态变量吗?例如: 这段代码可以编译,我想知道为什么要使用静态访问特权。 问题答案: 我已经从The Java Tutorials找到了 实例方法可以直接访问实例变量和实例方法。 实例方法可以直接访问类变量和类方法。 类方法可以直接访问类变量和类方法。 类方法不能

  • 本文向大家介绍Oracle静态注册与动态注册详解,包括了Oracle静态注册与动态注册详解的使用技巧和注意事项,需要的朋友参考一下 一、概述:   Oracle的注册就是将数据库作为一个服务注册到监听程序。客户端不需要知道数据库名和实例名,只需要知道该数据库对外提供的服务名就可以申请连接到这个数据库。这个服务名可能与实例名一样,也有可能不一样。   在数据库服务器启动过程中,数据库服务器会向监听程

  • 我找不到任何解释原因的好消息:

  • 本文向大家介绍如何在C#中订阅事件,我们可以在C#中为一个事件拥有多个订阅者吗?,包括了如何在C#中订阅事件,我们可以在C#中为一个事件拥有多个订阅者吗?的使用技巧和注意事项,需要的朋友参考一下 事件使类或对象在发生感兴趣的事件时通知其他类或对象。 引发事件的类称为发布者,而处理事件的类称为订阅者。 在事件中 一个事件可以有多个订阅者。订阅者可以处理来自多个发布者的多个事件。 没有订阅者的事件永远

  • 我正在寻找一种完全从代码创建发布/订阅主题的方法。我设法用域验证api验证域,但我找不到向项目注册域的api。这里描述的唯一方法https://cloud.google.com/pubsub/advanced#register与控制台的交互使用。