113

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;
Nicholas K
  • 15,148
  • 7
  • 31
  • 57
Ashu
  • 1,703
  • 4
  • 16
  • 23

4 Answers4

174

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.

Andrea T
  • 3,035
  • 4
  • 23
  • 39
  • 54
    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. – Warren Dew May 15 '15 at 15:34
  • 1
    "static class"? – Arun Raaj Jul 30 '18 at 00:16
  • 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. – gagarwa Jun 04 '20 at 09:22
  • Mockito cant mock static methods. You need to use Powermock to mock static methods – Jaison Varghese Jul 22 '20 at 16:31
77

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).

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • 11
    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. – Jason Polites Nov 14 '13 at 21:30
  • 5
    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. – Andrea T Sep 11 '14 at 13:33
  • 59
    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. – Andrea T May 17 '15 at 08:29
  • 7
    The answer by @AndreaT should be the accepted answer. – Chirag Agrawal Jun 01 '16 at 12:13
  • 3
    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. – mttdbrd May 09 '17 at 23:38
  • @mttdbrd 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... – Morfic Aug 02 '17 at 12:03
  • @Morfic 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. – mttdbrd Aug 04 '17 at 14:56
  • @mttdbrd 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. – michaelgulak Aug 29 '17 at 21:03
  • @michaelgulak 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." – mttdbrd Aug 29 '17 at 21:11
  • @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. – Majid Ali Khan Oct 10 '19 at 10:04
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.

Tom11
  • 2,419
  • 8
  • 30
  • 56
Subin Sebastian
  • 10,870
  • 3
  • 37
  • 42
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;
    }
}
Parth Solanki
  • 3,268
  • 2
  • 22
  • 41