2

I was exploring ways to do simple, plain-old file-based configuration in Java. I looked into Java's built-in Properties and the Apache Common Configuration library. For the latter, the distilled code is as follows:

Configurations configs = new Configurations();
Configuration config = null;
try
{
    config = configs.properties(new File("config.properties"));
}
catch (ConfigurationException cex)
{
}

long loadQPS = config.getInt("loadQPS");

The issue I have with this is that I find myself inserting this in every single class, which is suboptimal for at least two reasons: 1) I'm reading the file once for every class, when I should only read it once. 2) code duplication.

One obvious solution would be to create a Singleton configuration class that I then access from every other class. But surely this is a desired feature in almost every use case, so shouldn't it be included with the configuration library itself (am I missing something)? I also thought of using Spring configuration, which can create a Singleton configuration class for me, but isn't there too much overhead just for file-based configuration? (Spring's strength is in DI, as I understand.)

What's a good solution, or best practice (if there is one)?

EDIT: A simple static solution suggested in the answer:

public class ConfigClass {

    static Configuration config;

    static {
        Configurations configs = new Configurations();

        Logger sysLogger = LoggerFactory.getLogger("sysLogger");
        try
        {
            config = configs.properties(new File("config.properties"));
        }
        catch (ConfigurationException cex)
        {
            sysLogger.error("Config file read error");
        }
    }
}

Access in the package by ConfigClass.config.

flow2k
  • 3,999
  • 40
  • 55
  • Also, on a separate note, `Configuration config = null;` does not seem very elegant. Suggestions are welcome! – flow2k Sep 08 '18 at 00:58

1 Answers1

3

So you have a couple options. One simple one would be to store and access the Configuration object statically.

Another one that I like when I want Dependency Injection without Spring, is to structure program in DI friendly way. You can emulate a DI container by transforming your main() function into a "configuration" of your program that ultimately launches it.

Consider a typical multi-tier web application: A DI friendly main() method might look like:

public class AddressBookApp {
  public static void main(String[] args) {
    Configuration conf = new Configuration(args[0]);

    // Creates our Repository, this might do some internal JDBC initialization
    AddressBookRepository repo = new AddressBookRepository(conf);

    // Pass the Repository to our Service object so that it can persist data
    AddressBookService service = new AddressBookService(repo);

    // Pass the Service to the web controller so it can invoke business logic
    AddressBookController controller = new AddressBookController(conf, service);

    // Now launch it! 
    new WebApp(new Controller[] { controller }).start();
  }
}

This main() serves as a central place to "wire up" your application so it's easy to pass your Configuration object to every component that needs it.

jeff
  • 4,325
  • 16
  • 27
  • Thanks! I decided to go with the simple static field for now - appended my code to the question above. – flow2k Sep 10 '18 at 05:16