Walk Through the Code
Let’s inject a bean into a static field with @Autowired in Spring.
Assume the following code exists.
@Component
class Something {
public void sayHi() {
System.out.println("Hi");
}
}
class Someone {
// want to use it...
@Autowired
public static SomeObject someObject;
public static void say() {
someObject.sayHi();
}
}
// config omitted
public class InjectionTest {
@Test
public void method() {
// NullPointerException
Someone.say();
}
}
Running this throws NullPointerException.
Something is created after the Someone class is loaded, so the bean does not exist at class-load time.
More importantly, @Autowired works only for classes managed by Spring.
Someone is not a Spring bean, so Spring never injects it.
Even if it were managed, the Spring context is not ready at class-load time, so static injection still fails.
Fix
First, make the class Spring-managed.
@Component
class Someone {
// ...
}
Then assign the injected instance during construction.
You can use a constructor or a setter, or use @PostConstruct.
@Component
class Someone {
public static SomeObject someObject;
// Option 1) setter
@Autowired
public void setSomeObject(SomeObject someObject) {
this.someObject = someObject;
}
// Option 2) constructor
@Autowired
private Someone(SomeObject someObject) {
this.someObject = someObject;
}
public static void say() {
someObject.sayHi();
}
}
@Component
class Someone {
@Autowired
private SomeObject beanObject;
public static SomeObject someObject;
@PostConstruct
private void initialize() {
this.someObject = beanObject;
}
public static void say() {
someObject.sayHi();
}
}