Why can't we autowire static fields in spring?
Asked Answered
A

4

114

Why can't we autowire the static instance variable in the Spring bean. I know there is another way to achieve this but just want to know why cant we do it in below way.

e.g.

@Autowired
public static Test test;
Ames answered 7/6, 2012 at 19:24 Comment(2)
can you shred some light on the alternate way you are referring to.Alishiaalisia
You can autowire through the constructor or use @PostConstuctShinn
E
78

Because using static fields encourages the usage of static methods. And static methods are evil. The main purpose of dependency injection is to let the container create objects for you and wire them. Also it makes testing easier.

Once you start to use static methods, you no longer need to create an instance of object and testing is much harder. Also you cannot create several instances of a given class, each with a different dependency being injected (because the field is implicitly shared and creates global state - also evil).

Ebro answered 7/6, 2012 at 19:27 Comment(10)
The one caveat to this that I've encountered is during testing. If you want to use @BeforeClass in a SpringJUnit4ClassRunner, and have that method access beans @Autowired in the test.. you basically can't. Which is annoying.Hermit
This answer explains why it shouldn"t. But the real motive is that when the framework try to wire the static class into a bean it may be not yet loaded by class loader.Heavy
This answer is complete senseless. Spring doesn't impose your testing strategy. The answer is that there isn't yet Spring library loaded when static Class are instantiated by class loader.Heavy
The answer by @AndreaT should be the accepted answer.Pamphleteer
Static methods are EASIER to test, not harder. Having spring automatically inject dependencies seems nice but that's actually the harder route for testing. Mocks, stubs, and test doubles are code smells, not static methods.Magdamagdaia
@Magdamagdaia that is an interesting concept, could you please share with us why you feel that way? I was under the impression that static methods make inheritance difficult as well as abstraction...Doradorado
@Doradorado Static methods, written properly, do not have state. Written properly, they do not have side effects. If you write your static methods with functional concepts in mind ("data in, data out"), testing them is easy: they simply perform transformations on data that makes them extremely easy to test. Search "Functional Core, Imperative Shell" and you'll find some good information on the benefits of this style of programming. I guess I should also say that inheritance is overrated.Magdamagdaia
@Magdamagdaia But even if static methods are written in a stateless fashion, they can easily call other static methods, which makes it more difficult to write good, isolated unit tests for them.Phosphate
@Phosphate Sure developers can do all kinds of stupid things so let's write stateful code since that's what they're going to do anyway! Sorry for the snark, but I don't really see the "evil."Magdamagdaia
@JasonPolites referring to your very first comment, well you should use constructor autowiring to access the fields because with field autowiring you can't do it and this is why it is not recommended by many. I know you would have figured it by now but in case.Tiernan
H
179

We can't autowire static fields in spring because the Spring context might not be loaded when the java class loader loads the static values. In that case the class loader won't properly inject the static fields in the bean and will fail.

Heavy answered 19/2, 2014 at 8:49 Comment(4)
Thanks for an answer that appears to actually answer the question rather than just voicing an opinion that half of the Java language is a bad idea.V
"static class"?Cajeput
This doesn't seem correct, as Mockito is able to inject objects into static fields, similar to how spring does autowiring...though I don't know if implementation is same. Need more info.Shinn
Mockito cant mock static methods. You need to use Powermock to mock static methodsCochlea
E
78

Because using static fields encourages the usage of static methods. And static methods are evil. The main purpose of dependency injection is to let the container create objects for you and wire them. Also it makes testing easier.

Once you start to use static methods, you no longer need to create an instance of object and testing is much harder. Also you cannot create several instances of a given class, each with a different dependency being injected (because the field is implicitly shared and creates global state - also evil).

Ebro answered 7/6, 2012 at 19:27 Comment(10)
The one caveat to this that I've encountered is during testing. If you want to use @BeforeClass in a SpringJUnit4ClassRunner, and have that method access beans @Autowired in the test.. you basically can't. Which is annoying.Hermit
This answer explains why it shouldn"t. But the real motive is that when the framework try to wire the static class into a bean it may be not yet loaded by class loader.Heavy
This answer is complete senseless. Spring doesn't impose your testing strategy. The answer is that there isn't yet Spring library loaded when static Class are instantiated by class loader.Heavy
The answer by @AndreaT should be the accepted answer.Pamphleteer
Static methods are EASIER to test, not harder. Having spring automatically inject dependencies seems nice but that's actually the harder route for testing. Mocks, stubs, and test doubles are code smells, not static methods.Magdamagdaia
@Magdamagdaia that is an interesting concept, could you please share with us why you feel that way? I was under the impression that static methods make inheritance difficult as well as abstraction...Doradorado
@Doradorado Static methods, written properly, do not have state. Written properly, they do not have side effects. If you write your static methods with functional concepts in mind ("data in, data out"), testing them is easy: they simply perform transformations on data that makes them extremely easy to test. Search "Functional Core, Imperative Shell" and you'll find some good information on the benefits of this style of programming. I guess I should also say that inheritance is overrated.Magdamagdaia
@Magdamagdaia But even if static methods are written in a stateless fashion, they can easily call other static methods, which makes it more difficult to write good, isolated unit tests for them.Phosphate
@Phosphate Sure developers can do all kinds of stupid things so let's write stateful code since that's what they're going to do anyway! Sorry for the snark, but I don't really see the "evil."Magdamagdaia
@JasonPolites referring to your very first comment, well you should use constructor autowiring to access the fields because with field autowiring you can't do it and this is why it is not recommended by many. I know you would have figured it by now but in case.Tiernan
A
18

According to OOP concept, it will be bad design if static variables are autowired.

Static variable is not a property of Object, but it is a property of a Class. Spring auto wiring is done on objects, and that makes the design clean in my opinion. You can deploy the auto wired bean object as singleton, and achieve the same as defining it static.

Aisne answered 8/6, 2012 at 7:35 Comment(0)
D
18

By this solution you can autowired static fields in spring.

@Component
public class TestClass {

    private static Test test;

    @Autowired
    public void setTest(Test test) {
        TestClass.test = test;
    }
}
Decadence answered 20/9, 2016 at 8:53 Comment(3)
Bugfinder will complain about setting up static field from non static method.Harding
@Harding referencing static members from non-static ones works, the inverse doesn'tRightminded
The question asked is WHY not HOWDrandell

© 2022 - 2024 — McMap. All rights reserved.