【问题标题】:Guice: how do you configure an @Provides and @Singleton in a module in this case?Guice:在这种情况下,如何在模块中配置 @Provides 和 @Singleton?
【发布时间】:2013-04-11 19:29:35
【问题描述】:

我在一个模块中有一个提供者方法,用 @Provides 注释:

@Provides
public ChatServicePerformanceMonitor getChatServicePerfMon() {
  ...
}

我已经用@Singleton 注释了我的ChatServicePerformanceMonitor。在我使用这个实例的代码中,我不能让 guice “被动地”注入它,因为我正在使用一个构建封闭类的框架(它不使用 Guice,所以这是我知道的唯一方法获取参考):

chatServicePerfMon = injector.getInstance(ChatServicePerformanceMonitor.class);

Guice 似乎不尊重我的ChatServicePerformanceMonitor 类上的@Singleton 注释。我每次调用 injector.getInstance(ChatServicePerformanceMonitor.class) 都会得到一个实例。

@Singleton 添加到提供程序方法似乎可以解决此问题:

@Provides @Singleton
public ChatServicePerformanceMonitor getChatServicePerfMon() {
  ...
}

这是预期的行为吗?似乎实例上的@Singleton 应该是我所需要的。

【问题讨论】:

  • 你是如何在你的第一个代码 sn-p 中创建 ChatServicePerformanceMonitor 的?如果 Guice 没有在您的 getChatServicePerfMon 方法中创建它,那么 @Singleton 将被忽略。
  • 是的,它是在 @Provider 方法中构造的,几乎与 provideTransactionLog 方法中的 here 描述的完全一样。似乎这一定是我正在做的事情,因为其他人一定有这个问题。但除了我直接从注入器获取实例之外,我看不出任何与他们的示例没有真正不同的东西。

标签: guice


【解决方案1】:

与此同时,此功能可用(使用 Guice 4.0 测试)。

@Provides 方法现在也可以用@Singleton 注释以应用范围。见https://github.com/google/guice/wiki/Scopes

【讨论】:

    【解决方案2】:

    如果您要像这样创建ChatServicePerformanceMonitor

    @Provides
    public ChatServicePerformanceMonitor getChatServicePerfMon() {
      return new ChatServicePerformanceMonitor();
    }
    

    那么你的类级别 @Singleton 注释将无效,因为 Guice 没有创建对象,你是。 Guice 只能对它创建的对象强制执行范围。将@Singleton 添加到您的getChatServicePerfMon() 方法没有任何问题。

    如果您在 ChatServicePerformanceMonitor 类上有一个无参数构造函数(或 @Inject 构造函数)并且您删除了您的 @Provides 方法,那么对注入器的持续调用将返回相同的单例。

    【讨论】:

    • 好的,谢谢。我正在那里做一个新的。我想既然 Guice 正在调用我的提供程序方法,我认为它仍然会强制执行单例行为(因为我不调用提供程序方法,所以他们这样做了)并且可以管理它。猜我错了!
    • 我不知道您使用的是哪个框架,但您也可以使用 Guice 通过Provider(或@987654330)创建封闭实例(即使您无法注入其中) @)。这样该对象就可以与其他 Guice 依赖项协作。
    • 谢谢,是的,我一直在寻找一种方法来做到这一点,但是这个框架“工作”的方式是我扩展了他们的一个类。他们在启动时引导所有内容(它是一个名为 SmartFox 的游戏服务器),并进行扩展类实例化。我认为没有办法让 Guice 拦截它,是吗?
    • 根据经验:使用 DI/Guice 时,切勿使用“新”一词。
    • "Guice 只能在它创建的对象上强制作用域" Guice 正在创建对象。它只是调用我们的Provides 方法而不是调用类构造函数。在这种情况下,我认为它没有理由不遵守 @Singleton 类注释。
    【解决方案3】:

    你总是可以只做非常简单的方法:

    private ChatServicePerformanceMonitor perfMon = null;
    
    @Provides
    public ChatServicePerformanceMonitor getChatServicePerfMon() {
      if (perfMon == null) {
        perfMon = new ChatServicePerformanceMonitor();
      }
    
      return perfMon;
    }
    

    【讨论】:

    • 这似乎不是线程安全的,应该在方法上包含同步关键字
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多