【问题标题】:What is the proper idiom for using the built in Guice Injection for annotating static java.util.Logger instances?使用内置 Guice 注入来注释静态 java.util.Logger 实例的正确习惯用法是什么?
【发布时间】:2011-08-19 15:46:15
【问题描述】:

我想开始使用 Guice 3.x 神奇地注入我的 java.util.logging.Logger 实例。

这是我尝试开始工作的一段代码:

@Singleton
public class Main
{
    @Inject
    private static final Logger logger;

...
}

这似乎不起作用。

无论我在声明中使用什么范围,我都会得到Exception in thread "main" java.lang.NullPointerException

我在configure() 方法中将super.requestStaticInjection(Main.class); 行添加到我的module 并开始工作,但前提是我删除final 关键字并使其成为static Logger logger

如果可能的话,我宁愿保留 Logger final

Guice 的正确惯用方式是什么?

【问题讨论】:

  • 我不做Guice,但对我来说注入static final“property”(它实际上是一个常量)是完全不可能的。我知道的所有依赖注入框架也不允许这样做。如果你摆脱了这些限制,它会起作用吗?
  • 将其更改为 @Inject public Logger logger 以及介于两者之间的所有范围,但仍然出现错误。我喜欢将任何不可变的东西标记为final,并且在每个对象上都有一个Logger 的实例并不好。
  • 嗯,这可能是指南配置问题。顺便说一句,您会遇到什么错误?熟悉 Guice 的人或许可以通俗地为您翻译,让您了解原因,从而找到解决方案。
  • @BalusC,你是完全正确的。 Guice 无法设置最终的静态属性。这就是 Java 的设计方式以及 final 修饰符的用途。

标签: java logging guice idioms java.util.logging


【解决方案1】:

您可以在 guice 中注入静态属性,例如

class Dummy {
   @Inject static Foo;
}

requestStaticInjection(Dummy.class);

在注入器中配置模块。

【讨论】:

  • 有什么魔法咒语可以让我也完成它吗?
  • 恐怕不会......因为当你的类加载时,最终属性设置为null。除非另有(明确)说明,否则在实例化对象时,所有对象字段都使用默认值进行初始化。所有未设置(未在任何构造函数或静态初始化块中设置)static 字段在类加载期间接收默认值。所以,当你想设置它时已经太晚了,因为它已经持有null
  • 感谢您确认我在等待答复时发现的内容!
【解决方案2】:

Guice 确实允许最终字段注入,但不建议这样做

绑定的值被设置到字段中。不推荐注入 final 字段,因为注入的值可能对其他线程不可见。

source,也知道set() 的所有警告。

这意味着你可以有一个 final 字段,但不能注入一个静态的 final 字段

如果基础字段是最终字段,则该方法将抛出 IllegalAccessException,除非该字段的 setAccessible(true) 已成功并且该字段是非静态的。

另一方面,JSR 330 不允许注入 final 字段。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    • 1970-01-01
    • 2018-11-23
    • 1970-01-01
    • 2015-04-28
    • 2022-10-02
    相关资源
    最近更新 更多