Correctness3 - SpotBugsExtensionForSpringFrameWork/CS5098 GitHub Wiki
Correctness - Inject a Value to static field
Description
Injected a value from a Java properties file to a static field with Spring, the parameter will be null when we apply the @Value
annotation on an instance field:
@Value("${name}")
private static String A_NULL_PARAMETER;
Because Spring doesn't support @Value
on static fields.
Theory
After a bean is instantiated, assembly of that bean will be performed by the Spring IoC container. BeanPostProcessor
Interface is the first step to modify the bean's configuration. In this case, we use @Value
annotation to inject properties. Therefore, AutowiredAnnotationBeanPostProcessor
which is the implementation of BeanPostProcessor
will be called to autowire annotated fields after construction of a bean.
After that, postProcessMergedBeanDefinition
method will be called to handle field or method injection. Metadata will be injected by calling findAutowiringMetadata
.
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
buildAutowiringMetadata
method inside findAutowiringMetadata
will take all the fields and methods with @Autowired
out and examine whether the modifier is static or not.
ReflectionUtils.doWithLocalFields(targetClass, field -> {
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
Therefore, static field is not allowed to inject value.
Solution
Create a setter method called setParamStatic and annotate it with the @Value
annotation:
@Controller
public class PropertyController {
@Value("${name}")
private String PARAM;
private static String PARAM_STATIC;
@Value("${name}")
public void setParamStatic(String PARAM){
PropertyController.PARAM_STATIC = PARAM;
}
}
References
- Baeldung - Injecting a Value in a Static Field in Spring
- Stack Overflow - Spring: How to inject a value to static field?