Spring – Inject value into static variables
Spring doesn’t allow to inject value into static variables, for example:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class GlobalValue {
@Value("${mongodb.db}")
public static String DATABASE;
}
If you print out the GlobalValue.DATABASE
, a null
will be displayed.
GlobalValue.DATABASE = null
Solution
To fix it, create a “none static setter” to assign the injected value for the static variable. For example :
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class GlobalValue {
public static String DATABASE;
@Value("${mongodb.db}")
public void setDatabase(String db) {
DATABASE = db;
}
}
Output
GlobalValue.DATABASE = "mongodb database name"
This fix is giving me sonar error. Correctly updating a static field from a non-static method is tricky to get right and could easily lead to bugs if there are multiple class instances and/or multiple threads in play. Ideally, static fields are only updated from synchronized static methods.
This rule raises an issue each time a static field is updated from a non-static method.
This isn’t working for me. In main(), restUrl is always null;
public static String RESTURL;
@Value(“${restUrl}”)
public void setUrl(String url)
{
RESTURL = url;
}
I think you’re missing a @Component or @Service annotation in your class. Replying here just in case someone else faces this problem.
try this way:
@Service
public class UserService {
private final String restUrl;
@Autowired
public UserService(@Value(“${restUrl}”) String restUrl) {
this.restUrl= restUrl;
}
}
In my case the member variable is private. I do not want to make it modifiable from outside of the class.
I suppose there is no workaround that allows us to inject into
public static final
(Which would be ultimately awesome, I dont have a need for non final constants)
setter must be nonstatic , IDE generated setter method auto add static
I used setter way but I had to autowire it.
example
public static String DATABASE;
@Autowired
public void setDatabase( @Value(“${mongodb.db}”) String db) {
DATABASE = db;
}
Can we do the same for a static final variable?
Thank you very much!
Just be sure that the class is @Component or @Service.
awsome!
Worked perfectly for me!
The question is – why would you want to do that in the first place? In the example here you’re making Spring do something that is generally considered as an anti-pattern, as in the end you end up with having a non-final static variable that only act as a constant (not to mention that you still instantiate the class just to set its static member).
If you’re using Spring, I’d suggest defining an immutable component (like DbConfiguration) with private final fields and then autowire it wherever necessary. This way you’ll make sure the injected values will not change during runtime (either on purpose, or by accident) and it’ll generally make your code better in terms of readability and testability.
I wanted to inject value into a helper util class.
hi,
I want to use a variable(which is reading properties from yml file with @Value) in static block. Please tell how to do this.
Thanks in advance.
Thankyou very much. An elegant solution.
How to inject a bean here and not just a value into static variables
I am new to spring and using Spring boot for my project. I have a mysql table of status which has id and status name as columns i want to load this in a static hashmap when i start the server and it should be available from my controllers. I created a bean and put the hashmap in it, but it is getting garbage collected I guess so I am getting nullpointer exception.
How to approach this? Any help will be appreciated.