I've been using java OWNER for property based configuration.
I've create a static method
public static final ApplicationConfiguration config = ConfigFactory.create(ApplicationConfiguration.class,
System.getProperties(), System.getenv());
and I import the class everywhere I need conf.
Needless to say, unit testing is a PITA. I couldn't find a good way of override the values in the configuration.
I would like to avoid passing the config as a dependency in every class. It adds a lot of verbosity and it doesn't make sense from a design point of view. Same applies for calling the config factory in every class
ApplicationConfiguration config = ConfigFactory.create(ApplicationConfiguration.class,
System.getProperties(), System.getenv());
Have you got any suggestion? is there a best practice?
Two things:
You can create a class that provides the properties and all users use it:
public class PropertiesAccessor {
private static MyConfiguration mMyConfig = ConfigFactory.create(MyConfiguration.class);
private PropertiesAccessor()
// No need to allow instantiation of this class
}
/**
* Get properties for this application
*
* @return Properties
*/
public static MyConfiguration getProperties() {
return mMyConfig;
}
// for unit testing
@VisibleForTesting
public static void setProperties(MyConfiguration config) {
mMyConfig = config;
}
}
Now, everywhere you need a property, you can use this static method
PropertiesAccessor.getProperties()
Notice that there is a method for testing, setProperties(). There are different ways to use this method. You can create a test property file, load it in, then call the setProperties() method. I like to have a utility method like this:
public static void initProperties(String fileName) {
Properties testProperties = new Properties();
File file = new File(fileName);
FileInputStream stream = null;
try {
stream = new FileInputStream(file);
testProperties.load(stream);
} catch (IOException e) {
// Log or whatever you want to do
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
// Log or whatever you want to do;
}
MyConfiguration config = ConfigFactory.create(MyConfiguration.class, testProperties);
PropertiesAccessor.setProperties(config);
}
Then, you can have various properties files.
Or, if you just want to set a few properties, do this:
Properties testProperties = new Properties();
testProperties.setProperty("key1", "data1");
testProperties.setProperty("key2", "data2");
final MyConfiguration myConfig = ConfigFactory.create(MyConfiguration.class, testProperties);
PropertiesAccessor.setProperties(myConfig);