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

Relevant Patterns

  1. Bad Practice - Injected a Value to static field