为什么在春季不能自动为静态场接线?


96

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

例如

@Autowired
public static Test test;

您是否可以简化所引用的替代方式的内容?
samshers

您可以通过构造函数自动
接线,

Answers:


69

因为使用静态字段会鼓励使用静态方法。静态方法是邪恶的。依赖项注入的主要目的是让容器为您创建对象并进行连接。而且,它使测试更加容易。

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


11
我遇到的一个警告是在测试期间。如果您想@BeforeClass在SpringJUnit4ClassRunner中使用,并且让该方法@Autowired在测试中访问bean ,那么基本上可以。真烦人。
杰森·波利特

4
这样的回答解释了为什么它不该“吨但真正的动机是,当框架尝试连线静态类成一个bean可以没有通过类加载器加载。
安德烈牛逼

51
这个答案是完全没有意义的。Spring不会强加您的测试策略。答案是,当通过类加载器实例化静态类时,尚未加载Spring库。
Andrea T

7
@AndreaT的答案应该是被接受的答案。
Chirag Agrawal

3
静态方法更容易测试,而不是更难。让spring自动注入依赖关系看起来不错,但这实际上是测试的更艰难的途径。嘲笑,存根和测试双打是代码味道,不是静态方法。
mttdbrd

150

因为当类加载器加载静态值时,Spring上下文不一定要加载。因此,类加载器不会正确地将静态字段注入Bean中,并且将失败。


46
感谢您提供的答案似乎实际上是在回答问题,而不是仅仅说一半的Java语言是一个坏主意。
沃伦·露

1
“静态课”?
阿伦·拉伊

这似乎不正确,因为Mockito能够将对象注入静态字段,类似于spring自动装配的方式...尽管我不知道实现是否相同。需要更多信息。
gagarwa

Mockito无法模拟静态方法。您需要使用Powermock模拟静态方法
Jaison Varghese

17

根据OOP的概念,如果自动连接静态变量将是不好的设计。

静态变量不是Object的属性,而是Class的属性。弹簧自动接线是在对象上完成的,因此我认为设计很干净。您可以将自动有线bean对象部署为单例,并实现与静态定义相同的目的。


15

通过此解决方案,您可以在春季自动接线静态场。

@Component
public class TestClass {

    private static Test test;

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

4
Bugfinder将抱怨通过非静态方法设置静态字段。
Neftanic '17

@Neftanic从非静态成员中引用静态成员是可行的,反之则不行
younes zeboudj
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.