【问题标题】:Why can't we autowire static fields in spring?为什么我们不能在 spring 中自动装配静态字段?
【发布时间】:2012-06-11 21:41:46
【问题描述】:

为什么我们不能在 Spring bean 中自动装配静态实例变量。我知道还有另一种方法可以实现这一点,但只是想知道为什么我们不能以下面的方式做到这一点。

例如

@Autowired
public static Test test;

【问题讨论】:

  • 你能解释一下你所指的替代方式吗?
  • 您可以通过构造函数自动装配或使用@PostConstuct

标签: spring autowired


【解决方案1】:

因为当类加载器加载静态值时,Spring 上下文还没有被加载。 所以类加载器不会正确地在 bean 中注入静态字段并且会失败。

【讨论】:

  • 感谢您的回答似乎实际上回答了这个问题,而不是仅仅表达一种观点,即一半的 Java 语言是一个坏主意。
  • “静态类”?
  • 这似乎不正确,因为 Mockito 能够将对象注入静态字段,类似于 spring 自动装配的方式......虽然我不知道实现是否相同。需要更多信息。
  • Mockito 不能模拟静态方法。你需要使用 Powermock 来模拟静态方法
【解决方案2】:

通过这个解决方案,您可以在春季自动装配静态字段。

@Component
public class TestClass {

    private static Test test;

    @Autowired
    public void setTest(Test test) {
        TestClass.test = test;
    }
}

【讨论】:

  • Bugfinder 会抱怨从非静态方法设置静态字段。
  • @Neftanic 从非静态成员中引用静态成员有效,反之则不行
【解决方案3】:

根据 OOP 的概念,如果静态变量是自动装配的,那将是糟糕的设计。

静态变量不是 Object 的属性,而是 Class 的属性。 弹簧自动布线是在对象上完成的,在我看来,这使设计更加简洁。 您可以将自动连接的 bean 对象部署为单例,并实现与将其定义为静态的相同。

【讨论】:

    【解决方案4】:

    因为使用静态字段鼓励使用静态方法。静态方法是邪恶的。依赖注入的主要目的是让容器为你创建对象并连接它们。它还使测试更容易。

    一旦您开始使用静态方法,您就不再需要创建对象实例并且测试变得更加困难。此外,您不能创建给定类的多个实例,每个实例都注入不同的依赖项(因为该字段是隐式共享的并创建全局状态 - 也是邪恶的)。

    【讨论】:

    • 我遇到的一个警告是在测试期间。如果你想在 SpringJUnit4ClassRunner 中使用 @BeforeClass,并在测试中让该方法访问 beans @Autowired .. 你基本上不能。这很烦人。
    • 这个答案解释了为什么不应该这样做。但真正的动机是,当框架尝试将静态类连接到 bean 时,它可能还没有被类加载器加载。
    • 这个答案完全没有意义。 Spring 不会强加您的测试策略。答案是类加载器实例化静态类时,还没有加载Spring库。
    • @AndreaT 的答案应该是公认的答案。
    • 静态方法更容易测试,而不是更难。让 spring 自动注入依赖项看起来不错,但这实际上是更难的测试途径。模拟、存根和测试替身是代码异味,而不是静态方法。
    猜你喜欢
    • 1970-01-01
    • 2012-02-14
    • 2018-12-19
    • 2015-06-03
    • 1970-01-01
    • 2012-10-05
    • 2015-07-28
    • 2017-12-08
    相关资源
    最近更新 更多