Categories
code-injection spring

Spring: How to inject a value to static field?

109

With this class

@Component
public class Sample {

    @Value("${my.name}")
    public static String name;


}

If I try Sample.name, it is always ‘null’. So I tried this.

public class Sample {

    public static String name;

    @PostConstruct
    public void init(){
        name = privateName;
    }

    @Value("${my.name}")
    private String privateName;

    public String getPrivateName() {
        return privateName;
    }

    public void setPrivateName(String privateName) {
        this.privateName = privateName;
    }  

}

This code works. Sample.name is set properly. Is this good way or not? If not, is there something more good way? And how to do it?

1

  • 3

    This won’t solve; if the static variable is used before object creation. e.g) if the static variable is used under static block to construct the resource, then the resource will be constructed with null.

    Nov 8, 2016 at 12:38

140

First of all, public static non-final fields are evil. Spring does not allow injecting to such fields for a reason.

Your workaround is valid, you don’t even need getter/setter, private field is enough. On the other hand try this:

@Value("${my.name}")
public void setPrivateName(String privateName) {
    Sample.name = privateName;
}  

(works with @Autowired/@Resource). But to give you some constructive advice: Create a second class with private field and getter instead of public static field.

8

  • 12

    For “public static non-final fields are evil”, could you please give me some references?

    – Anderson

    Jun 25, 2015 at 3:41

  • 9

    Non-final means you can modify the field value, which, for a static field, implies handling thread concurrency – a.k.a. pain in the stack.

    Jul 9, 2015 at 12:47

  • How to use @Value with Static block? Kindly guide us… Regards, Neha

    – user5268786

    Nov 18, 2015 at 11:28

  • 6

    Just FYI: The above code will cause a Sonar / Checkstyle violation (if you’re bothered about that kind of thing) as you have an instance method writing to a static field.

    – Neil

    Feb 10, 2016 at 10:52

  • 3

    It’s possible to mimick the final aspect by using a static setter which will only set the value if it’s currently null. So you allow only one modification of the field. (which of course has been made private and use a getter to access it). Spring can call static method in his configuration phase (XML or Annotation).

    – Walfrat

    Nov 16, 2016 at 15:29

2

Soruce of this info is this: https://www.baeldung.com/spring-inject-static-field

Spring uses dependency injection to populate the specific value when it finds the @Value annotation. However, instead of handing the value to the instance variable, it’s handed to the implicit setter instead. This setter then handles the population of our NAME_STATIC value.

    @RestController 
//or if you want to declare some specific use of the properties file then use
//@Configuration
//@PropertySource({"classpath:application-${youeEnvironment}.properties"})
public class PropertyController {
 
    @Value("${name}")//not necessary
    private String name;//not necessary
 
    private static String NAME_STATIC;
 
    @Value("${name}")
    public void setNameStatic(String name){
        PropertyController.NAME_STATIC = name;
    }
}

    0

    This is my sample code for load static variable

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    @Component
    public class OnelinkConfig {
        public static int MODULE_CODE;
        public static int DEFAULT_PAGE;
        public static int DEFAULT_SIZE;
    
        @Autowired
        public void loadOnelinkConfig(@Value("${onelink.config.exception.module.code}") int code,
                @Value("${onelink.config.default.page}") int page, @Value("${onelink.config.default.size}") int size) {
            MODULE_CODE = code;
            DEFAULT_PAGE = page;
            DEFAULT_SIZE = size;
        }
    }