It's not possible to use #Value on a static variable.
#Value("${some.value}")
static private int someValue;
static public void useValue() {
System.out.println(someValue);
}
When I do this, 0 is printed. So what is a good alternative to this?
Spring inject noting in static field (by default).
So you have two alternatives:
(the better one) make the field non static
(the ugly hack) add an none static setter which writes in the static field, and add the #Value annotation to the setter.
and then there is the trick with the MethodInvokingFactoryBean -- this example is for autowired fiels, but I guess you can adapt it for #Value too
Use this simple trick to achieve what you want (way better than having the value injected into non-static setters and writing so a static field - as suggested in the accepted answer):
#Service
public class ConfigUtil {
public static ConfigUtil INSTANCE;
#Value("${some.value})
private String value;
#PostConstruct
public void init() {
INSTANCE = this;
}
public String getValue() {
return value;
}
}
Use like:
ConfigUtil.INSTANCE.getValue();
To prevent ever repeating injections of the same value making a field non-static in a class that gets instantiated very often, I preferred to create a simple Singleton ConfigUtil as a workaround:
package de.agitos.app.util;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.annotation.Value;
/**
* Helper class to get injected configuration values from static methods
*
* #author Florian Sager
*
*/
#Configurable
public class ConfigUtil {
private static ConfigUtil instance = new ConfigUtil();
public static ConfigUtil getInstance() {
return instance;
}
private #Value("${my.value1}") Integer value1;
public Integer getValue1() {
return value1;
}
}
Inside the class I tried to inject the value first as a static Integer:
private static Integer value1 = ConfigUtil.getInstance().getValue1();
The following codes work for me,
public class MappingUtils {
private static String productTypeList;
#Value("${productType-list}")
public void setProductTypeList(String productTypeList) {
MappingUtils.getProductTypeList = productTypeList;
}
}
let's say you have a class name called config
so you initialize the static variable.
May be one can use the below approach for the same
class Config
{
private static int someValue;
private Config(#Value("${some.value}") int valueDuringInitialization)//private constructor
{
Config.someValue=valueDuringInitialization;
}
static public void useValue() {
System.out.println(someValue);
}
}
Related
In one of our legacy code base, I found the following pattern being used which seems to be a bit fragile. Consider the following Spring Bean:
#Component
public class PropsProvider {
private static Properties props;
#Inject
PropsProvider(Configuration config) {
PropsProvider.props = ConfigurationConverter.getProperties(config);
}
public static String getProperty(String key) {
return props.getProperty(key);
}
}
which will then be referred inside a plain Java class in a static way as shown below:
public class UrlUtil {
private static String IMAGE_URL;
static {
IMAGE_URL = PropsProvider.getProperty("image_url");
}
private UrlUtil() {}
public static void String getImageUrl() {
return IMAGE_URL;
}
}
Can there be an instance where during the server start-up time, the static block in UrlUtil gets executed before the Spring bean PropsProvider gets initalized leading to UrlUtil.getImageUrl() returning null to some caller class?
I have a Java program that should read configuration parameters from file, Like this:
java -jar myapp.jar --config config.txt ...
Once loaded, these parameters do not change and should be accessible by any class in the program.
Is it possible to make these parameters accessible from any class without explicitly adding them as parameter to constructors and methods? For example, I would like to be able to do this:
public class Main {
public static void main(String[] args){
// This list should be visible by any class
List<String> CONFIGS= readMyConfigsFromFile(args[0]);
...
}
}
public class MyClass(){
public MyClass(){
String thisConf= CONFIGS.get(0); // Do something with this conf param taken from Main.
...
}
}
public class MyOtherClass(){
public MyOtherClass(){
String thisConf= CONFIGS.get(0); // Do something with this conf param taken from Main.
...
}
}
...
Is this possible at all? And is it an advisable set up to do? If not, what is the recommended design to go about it?
(I have read similar questions but I'm still unsure if and how it is possible in the situation I described)
You could use the Singleton pattern.
To model it, I assume you have 2 fields in your configuration: a String and an integer.
public class Config {
private static Config INSTANCE;
private final String field1;
private final int field2;
public Config(String field1, int field2) {
this.field1 = field1;
this.field2 = field2;
}
public String getField1() {
return field1;
}
public int getField2() {
return field2;
}
public static Config getInstance() {
if (INSTANCE == null) {
INSTANCE = loadInstance();
}
return INSTANCE;
}
private static Config loadInstance() {
// read your config from properties
String field1 = ...
int field2 = ...
return new Config(field1, field2);
}
}
And then use Config.getInstance() everywhere you need to get that instance.
Please note that this implementation has a flaw: it may be initialized several times if getInstance() gets called from different theads.
Double-checked locking https://en.wikipedia.org/wiki/Double-checked_locking may be used to overcome this flaw if it is important to you to only initialize once.
This solution, like others, would require a mock object to unit test. But I think it's best as it encapsulates the arguments in an immutable object. This also makes thread-safety a non-issue. Use a HashMap instead of an array to access these by key instead of index if you prefer:
public class Main {
public static void main(String[] args){
new CONFIG(readMyConfigsFromFile(args[0]).toArray());
...
}
public static final class CONFIG {
private final String[] args;
private static final CONFIG instance;
private CONFIG(String[] args) {
this.args = args;
instance = this;
}
public static CONFIG getInstance() {
return CONFIG.instance;
}
public String[] getArgs(){
return Arrays.copy(this.args, this.args.length);
}
public String getArg(int index) {
return args[index];
}
}
To get arguments:
Main.CONFIG.getArgs();
"Is this possible at all?". Yes, it is. You can easily do it with the help of static in java
public class Config {
private static final List<String> config = new ArrayList<String>();
public static void addConfig(String value){
config.add(value);
}
public static List<String> getConfig(){
return config;
}
}
To add values to config you can do
public static void main(String[] args) {
//Read value from file here in some variable say configValue
Config.addConfig(configValue);
}
To access config
public class MyOtherClass(){
public MyOtherClass(){
Config.getConfig().get(0); // Do something with this conf param taken from Main.
...
}
}
Note above code is not thread safe. You can make it thread safe by adding synchronization concepts
Now "And is it an advisable set up to do?". It depends on your requirements. As you mentioned these values does not change runtime then you can use this. But is the requirement we need to enforce that these values "should not change" once initialized then answer will be different and you should use something like Singleton Pattern and modify to make sure you can only read and not write once the object is constructed. Also note that with static methods, like I suggested, testing becomes really hard.
For example a class:
//class1
class A {
private A() { } // why would I make it private?
public A(int) { } //why isn't it implicitly public?
}
//class2
class B {
public static void main(String[] args) {
//A a = new A();
}
}
A constructor instantiates a class so why it has the access modifier?
Is there a case when we have to declare a constructor private?
A constructor instantiates a class so why it has the access modifier?
The modifier can be used so you control where the object can be constructed.
Is there a case when we have to declare a constructor private?
Say you have a factory method like
class A {
private A(int n) { }
public static A create(int n) {
return new A(n);
}
}
or you have a shared constructor which should be called directly.
class B {
public B(int n) {
this(n, "");
}
public B(String str) {
this(0, str);
}
private B(int n, String str) { }
}
or you have a Singleton
final class Singleton {
Singleton INSTANCE = new Singleton();
private Singleton() { }
}
however I prefer to use an enum which has a private constructor.
enum Singleton {
INSTANCE;
}
or you have a Utility class
final class Utils {
private Utils() { /* don't create one */ }
public static int method(int n) { }
}
however I prefer to use an enum in this case
enum Utils {
/* no instances */;
public static int method(int n) { }
}
Note: if you use a private constructor on a final class you can still create instances using nested classes, or reflection. If you use an enum you can't create an instance as easily/accidentally.
Warning: You can create instances of an enum using Unsafe
Note in enum the constructor has to be private
class BuySell {
BUY(+1), SELL(-1);
private BuySell(int dir) { }
}
You don't have to make it private explicitly as this is the default.
The private modifier when applied to a constructor works in much the same way as when applied to a normal method or even an instance variable. Defining a constructor with the private modifier says that only the native class (as in the class in which the private constructor is defined) is allowed to create an instance of the class, and no other caller is permitted to do so. There are two possible reasons why one would want to use a private constructor – the first is that you don’t want any objects of your class to be created at all, and the second is that you only want objects to be created internally – as in only created in your class.
Uses of private construtor:-
1) Private constructors can be used in the singleton design pattern
2) Private constructors can prevent creation of objects
This might also help Can a constructor in Java be private? the use cases of private constructor
Constructor are not responsible for Creating a object of a Class, these constructor are only responsible for initialize the member variables only.
There are various Reason behind this. One of the most popular reason behind this is design-Pattern.
//class1
class A {
private A() { } // why would I make it private?
}
why make private Constructor ?
If you want to make a Class singleton then your constructor must be private. then only it is possible to make a Class a Singleton.
I'm using PowerMock with EasyMock, and wondered how I might mock a singleton with a private constructor?
Let's say I have the following class:
public class Singleton {
private static Singleton singleton = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return singleton;
}
public int crazyServerStuff() { ... }
}
And a class which uses this:
public class Thing {
public Thing() {}
public int doStuff(Singleton s) {
return s.crazyServerStuff() + 42;
}
}
How might I mock the crazyServerStuff method?
I've tried the following:
#RunWith(PowerMockRunner.class)
#PrepareForTest(Singleton.class)
public class ThingTest extends AndroidTestCase {
#Test
public void testDoStuff() {
MemberModifier.suppress(MemberModifier.constructor(Singleton.class));
Singleton mockSingleton = PowerMock.createMock(Singleton.class);
...
}
}
But I get the error java.lang.IllegalArgumentException: No visible constructors in class Singleton
Does anyone know what I'm missing?
I don't think you should suppress the constructor, but rather mock it:
PowerMock.expectNew(Singleton.class).andReturn(mockObject)
https://code.google.com/p/powermock/wiki/MockConstructor
Sadly I don't think this is possible for Android - see this answer.
If you're not on Android, it looks like this is how you do it.
I created SomeConfig to store there static data. However I try to understand witch options is better (or none of both)
Before I had class SomeConfig written like:
public class SomeConfig {
private static int mValue = 8;
private static String mString = "some String";
public static int getValue() {
return mValue;
}
public static void setValue(int value) {
mValue = value;
}
public static String getTheString() {
return mString;
}
public static void setValue(String theString) {
mString = theString;
}
}
Now I changed it to:
public class SomeConfig {
private static SomeConfig mSomeConfig = new SomeConfig();
private int mValue = 8;
private String mString = "some String";
public static int getValue() {
return mSomeConfig.mValue;
}
public static void setValue(int value) {
mSomeConfig.mValue = value;
}
public static String getTheString() {
return mSomeConfig.mString;
}
public static void setValue(String theString) {
mSomeConfig.mString = theString;
}
}
Generally i changed private variables to non-static but API stays the same.
What is a difference between two options I posted?
Thanks,
If you want only one instance of your SomeConfig to exist in your application then you might want to make it a Singleton class. Refer to this link : link
Your second option seems to be the closest to being a Singleton, you just need to make your Default constructor Private to ensure that no other class can create another instance of SomeConfig.
As per my understanding static variables are class variable and those are not require any object for calling or assigning value .The values for those static variables are remains same over the class.Once you assign a value, all object can access that value.
Hope it will help you.
Generally, I think it's a good practice to avoid static variables and methods, unless there is a real need (I guess common use of static is "utility" type method, or constants etc). If you do not want to instantiate the class multiple times or want to ensure single instance of the configuration, I think implementing it as a singleton would be a better way to go here.
I wouldn't recommend using any of the two for configuration purposes.
The difference between these two are just that one uses an instance to hold the values, the other uses static variables.
You might look into having a configuration class that utilises a ResourceBundle to load the values from a .properties file during initialisation.